<!DOCTYPE html>
<html lang="zh_CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <meta name="generator" content="VuePress 2.0.0-beta.45">
    <style>
      :root {
        --c-bg: #fff;
      }
      html.dark {
        --c-bg: #22272e;
      }
      html, body {
        background-color: var(--c-bg);
      }
    </style>
    <script>
      const userMode = localStorage.getItem('vuepress-color-scheme');
			const systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
			if (userMode === 'dark' || (userMode !== 'light' && systemDarkMode)) {
				document.documentElement.classList.toggle('dark', true);
			}
    </script>
    <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"><title>Gin 中文文档 | 科科人神</title><meta name="description" content="科科人神，后端软件工程师，喜欢云原生">
    <link rel="modulepreload" href="/assets/app.80e5dc69.js"><link rel="modulepreload" href="/assets/index.html.6ec0b380.js"><link rel="modulepreload" href="/assets/index.html.a2792a89.js"><link rel="prefetch" href="/assets/index.html.cba988ab.js"><link rel="prefetch" href="/assets/1.html.8ac90e92.js"><link rel="prefetch" href="/assets/19.html.4444be95.js"><link rel="prefetch" href="/assets/必备知识.html.7da85c42.js"><link rel="prefetch" href="/assets/必备知识罗列.html.5e18db77.js"><link rel="prefetch" href="/assets/1.html.356f0755.js"><link rel="prefetch" href="/assets/2.html.085440fc.js"><link rel="prefetch" href="/assets/3.html.09effb5c.js"><link rel="prefetch" href="/assets/1.html.50fb5135.js"><link rel="prefetch" href="/assets/1.html.17222973.js"><link rel="prefetch" href="/assets/1.html.0a197ef1.js"><link rel="prefetch" href="/assets/4-1.html.073fbd99.js"><link rel="prefetch" href="/assets/4-2.html.64039343.js"><link rel="prefetch" href="/assets/4.html.021c0881.js"><link rel="prefetch" href="/assets/5-6-1.html.34978ed1.js"><link rel="prefetch" href="/assets/5-6-2.html.f004f560.js"><link rel="prefetch" href="/assets/5-6.html.f5ad3835.js"><link rel="prefetch" href="/assets/index.html.467e6eba.js"><link rel="prefetch" href="/assets/index.html.f3622043.js"><link rel="prefetch" href="/assets/index.html.5d63961d.js"><link rel="prefetch" href="/assets/index.html.0b5fc023.js"><link rel="prefetch" href="/assets/index.html.2f735cf1.js"><link rel="prefetch" href="/assets/index.html.9d71a6d6.js"><link rel="prefetch" href="/assets/bash_completions.html.ed68147e.js"><link rel="prefetch" href="/assets/man_docs.html.2f0dd0c9.js"><link rel="prefetch" href="/assets/md_docs.html.20de452a.js"><link rel="prefetch" href="/assets/rest_docs.html.b77e8a2e.js"><link rel="prefetch" href="/assets/zsh_completions.html.60976ab2.js"><link rel="prefetch" href="/assets/syslog.html.48554683.js"><link rel="prefetch" href="/assets/daily_dep.html.2f155f5c.js"><link rel="prefetch" href="/assets/getting_started.html.769a2eaa.js"><link rel="prefetch" href="/assets/installation.html.e6b0002b.js"><link rel="prefetch" href="/assets/migrating.html.128871c1.js"><link rel="prefetch" href="/assets/new_project.html.8326d390.js"><link rel="prefetch" href="/assets/uninstalling.html.26650652.js"><link rel="prefetch" href="/assets/deduction.html.d4acd3fa.js"><link rel="prefetch" href="/assets/ensure_mechanics.html.603c62de.js"><link rel="prefetch" href="/assets/404.html.a15b4cbd.js"><link rel="prefetch" href="/assets/index.html.29aac47c.js"><link rel="prefetch" href="/assets/index.html.b64fbb23.js"><link rel="prefetch" href="/assets/index.html.cd48e230.js"><link rel="prefetch" href="/assets/index.html.6b048e76.js"><link rel="prefetch" href="/assets/index.html.7f0a6e54.js"><link rel="prefetch" href="/assets/index.html.b5a71586.js"><link rel="prefetch" href="/assets/index.html.60805430.js"><link rel="prefetch" href="/assets/index.html.60736b0b.js"><link rel="prefetch" href="/assets/index.html.80dddd6d.js"><link rel="prefetch" href="/assets/index.html.cc3c6a0d.js"><link rel="prefetch" href="/assets/index.html.44e62fda.js"><link rel="prefetch" href="/assets/index.html.015a0b2c.js"><link rel="prefetch" href="/assets/index.html.415d4517.js"><link rel="prefetch" href="/assets/index.html.d1d65e23.js"><link rel="prefetch" href="/assets/index.html.725ac526.js"><link rel="prefetch" href="/assets/index.html.c824ee30.js"><link rel="prefetch" href="/assets/1.html.4fb25663.js"><link rel="prefetch" href="/assets/19.html.ded8a9c9.js"><link rel="prefetch" href="/assets/必备知识.html.0ff3a77d.js"><link rel="prefetch" href="/assets/必备知识罗列.html.85e0f635.js"><link rel="prefetch" href="/assets/1.html.4f76037b.js"><link rel="prefetch" href="/assets/2.html.05a6e91e.js"><link rel="prefetch" href="/assets/3.html.30d4c4b6.js"><link rel="prefetch" href="/assets/1.html.ce86a757.js"><link rel="prefetch" href="/assets/1.html.0f8a9434.js"><link rel="prefetch" href="/assets/1.html.f4ee2fe7.js"><link rel="prefetch" href="/assets/4-1.html.c7cc75b6.js"><link rel="prefetch" href="/assets/4-2.html.36807608.js"><link rel="prefetch" href="/assets/4.html.c03ae622.js"><link rel="prefetch" href="/assets/5-6-1.html.651e5517.js"><link rel="prefetch" href="/assets/5-6-2.html.5ccfdb5e.js"><link rel="prefetch" href="/assets/5-6.html.882bc951.js"><link rel="prefetch" href="/assets/index.html.9d9ba895.js"><link rel="prefetch" href="/assets/index.html.3da373d1.js"><link rel="prefetch" href="/assets/index.html.f8c39be7.js"><link rel="prefetch" href="/assets/index.html.e8d4dc57.js"><link rel="prefetch" href="/assets/index.html.2275c56f.js"><link rel="prefetch" href="/assets/index.html.711c721b.js"><link rel="prefetch" href="/assets/bash_completions.html.31fa6426.js"><link rel="prefetch" href="/assets/man_docs.html.cc0f68c6.js"><link rel="prefetch" href="/assets/md_docs.html.dd10674f.js"><link rel="prefetch" href="/assets/rest_docs.html.46da86e5.js"><link rel="prefetch" href="/assets/zsh_completions.html.64d57b81.js"><link rel="prefetch" href="/assets/syslog.html.5324d692.js"><link rel="prefetch" href="/assets/daily_dep.html.b7a8b70b.js"><link rel="prefetch" href="/assets/getting_started.html.29c6534a.js"><link rel="prefetch" href="/assets/installation.html.b11da95a.js"><link rel="prefetch" href="/assets/migrating.html.92825adc.js"><link rel="prefetch" href="/assets/new_project.html.8fcfe511.js"><link rel="prefetch" href="/assets/uninstalling.html.34c1a6fb.js"><link rel="prefetch" href="/assets/deduction.html.2f0a618b.js"><link rel="prefetch" href="/assets/ensure_mechanics.html.7818d8b5.js"><link rel="prefetch" href="/assets/404.html.37719150.js"><link rel="prefetch" href="/assets/index.html.bc2fbcdd.js"><link rel="prefetch" href="/assets/index.html.2363e42b.js"><link rel="prefetch" href="/assets/index.html.691f6b43.js"><link rel="prefetch" href="/assets/index.html.c73599f4.js"><link rel="prefetch" href="/assets/index.html.32559aa6.js"><link rel="prefetch" href="/assets/index.html.283a60cc.js"><link rel="prefetch" href="/assets/index.html.b72bddc9.js"><link rel="prefetch" href="/assets/index.html.aebed871.js"><link rel="prefetch" href="/assets/index.html.1bace120.js"><link rel="prefetch" href="/assets/index.html.7913d44a.js"><link rel="prefetch" href="/assets/index.html.4e5360d4.js"><link rel="prefetch" href="/assets/index.html.028748b8.js"><link rel="prefetch" href="/assets/index.html.e9cb3a86.js"><link rel="prefetch" href="/assets/index.html.e31e8159.js"><link rel="prefetch" href="/assets/index.html.01049197.js"><link rel="prefetch" href="/assets/404.30cc8863.js"><link rel="prefetch" href="/assets/HomePage.4e823a0b.js"><link rel="prefetch" href="/assets/Layout.61f5e0fd.js"><link rel="prefetch" href="/assets/Links.8680cda6.js"><link rel="prefetch" href="/assets/Post.93b09438.js"><link rel="prefetch" href="/assets/Tags.3d9bb337.js">
    <link rel="stylesheet" href="/assets/style.8b24233a.css">
  </head>
  <body>
    <div id="app"><!--[--><div class="theme-container"><!--[--><header class="navbar is-fixed is-visible invert"><span><a href="/" class=""><span class="site-name">$ cd /home/</span></a></span><div class="navbar-items-wrapper" style=""><!--[--><!--]--><nav class="navbar-items can-hide"><!--[--><div class="navbar-item"><a href="/" class="" aria-label="home"><!--[--><!--]--><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="0 0 20 20" fill="currentColor"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"/></svg></span><span>home</span><!--[--><!--]--></a></div><div class="navbar-item"><a href="/tags/" class="" aria-label="归档"><!--[--><!--]--><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-1.6 -1.6 19.2 19.2" fill="currentColor"><path d="M2 2a1 1 0 011-1h4.586a1 1 0 01.707.293l7 7a1 1 0 010 1.414l-4.586 4.586a1 1 0 01-1.414 0l-7-7A1 1 0 012 6.586V2zm3.5 4a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"/><path d="M1.293 7.793A1 1 0 011 7.086V2a1 1 0 00-1 1v4.586a1 1 0 00.293.707l7 7a1 1 0 001.414 0l.043-.043-7.457-7.457z"/></svg></span><span>归档</span><!--[--><!--]--></a></div><div class="navbar-item"><a href="/links/" class="" aria-label="作品合集"><!--[--><!--]--><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-79.52 -43.52 599.04 599.04" fill="currentColor"><path d="M382.7 292.5l2.7 2.7-170-167.3c-3.5-3.5-9.7-3.7-13.8-.5L144.3 171c-4.2 3.2-4.6 8.7-1.1 12.2l68.1 64.3c3.6 3.5 9.9 3.7 14 .5l.1-.1c4.1-3.2 10.4-3 14 .5l84 81.3c3.6 3.5 3.2 9-.9 12.2l-93.2 74c-4.2 3.3-10.5 3.1-14.2-.4L63.2 268c-3.5-3.5-9.7-3.7-13.9-.5L3.5 302.4c-4.2 3.2-4.7 8.7-1.2 12.2L211 510.7s7.4 6.8 17.3-.8l198-163.9c4-3.2 4.4-8.7.7-12.2zm54.5-83.4L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7 171.7 165.1c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2z"/></svg></span><span>作品合集</span><!--[--><!--]--></a></div><!--]--><div class="navbar-item"><a style="cursor:pointer;"><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="0 0 24 24" fill="currentColor"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 2c4.968 0 9 4.032 9 9s-4.032 9-9 9-9-4.032-9-9 4.032-9 9-9zm0 16c3.867 0 7-3.133 7-7 0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7zm8.485.071l2.829 2.828-1.415 1.415-2.828-2.829 1.414-1.414z"/></svg></span><span>搜索</span></a></div></nav><!--[--><!--]--><!----></div></header><!--]--><div class="sidebar-mask"></div><!--[--><aside class="sidebar"><nav class="navbar-items"><!--[--><div class="navbar-item"><a href="/" class="" aria-label="home"><!--[--><!--]--><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="0 0 20 20" fill="currentColor"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"/></svg></span><span>home</span><!--[--><!--]--></a></div><div class="navbar-item"><a href="/tags/" class="" aria-label="归档"><!--[--><!--]--><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-1.6 -1.6 19.2 19.2" fill="currentColor"><path d="M2 2a1 1 0 011-1h4.586a1 1 0 01.707.293l7 7a1 1 0 010 1.414l-4.586 4.586a1 1 0 01-1.414 0l-7-7A1 1 0 012 6.586V2zm3.5 4a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"/><path d="M1.293 7.793A1 1 0 011 7.086V2a1 1 0 00-1 1v4.586a1 1 0 00.293.707l7 7a1 1 0 001.414 0l.043-.043-7.457-7.457z"/></svg></span><span>归档</span><!--[--><!--]--></a></div><div class="navbar-item"><a href="/links/" class="" aria-label="作品合集"><!--[--><!--]--><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-79.52 -43.52 599.04 599.04" fill="currentColor"><path d="M382.7 292.5l2.7 2.7-170-167.3c-3.5-3.5-9.7-3.7-13.8-.5L144.3 171c-4.2 3.2-4.6 8.7-1.1 12.2l68.1 64.3c3.6 3.5 9.9 3.7 14 .5l.1-.1c4.1-3.2 10.4-3 14 .5l84 81.3c3.6 3.5 3.2 9-.9 12.2l-93.2 74c-4.2 3.3-10.5 3.1-14.2-.4L63.2 268c-3.5-3.5-9.7-3.7-13.9-.5L3.5 302.4c-4.2 3.2-4.7 8.7-1.2 12.2L211 510.7s7.4 6.8 17.3-.8l198-163.9c4-3.2 4.4-8.7.7-12.2zm54.5-83.4L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7 171.7 165.1c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2z"/></svg></span><span>作品合集</span><!--[--><!--]--></a></div><!--]--><div class="navbar-item"><a style="cursor:pointer;"><span class="nav-icon"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="0 0 24 24" fill="currentColor"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 2c4.968 0 9 4.032 9 9s-4.032 9-9 9-9-4.032-9-9 4.032-9 9-9zm0 16c3.867 0 7-3.133 7-7 0-3.868-3.133-7-7-7-3.868 0-7 3.132-7 7 0 3.867 3.132 7 7 7zm8.485.071l2.829 2.828-1.415 1.415-2.828-2.829 1.414-1.414z"/></svg></span><span>搜索</span></a></div></nav><!--[--><!--]--><ul class="sidebar-items"><!--[--><li><p tabindex="0" class="sidebar-item sidebar-heading">Gin 中文文档 <!----></p><ul style="" class="sidebar-item-children"><!--[--><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#contents" class="router-link-active router-link-exact-active sidebar-item" aria-label="Contents"><!--[--><!--]--><!----><span>Contents</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#安装" class="router-link-active router-link-exact-active sidebar-item" aria-label="安装"><!--[--><!--]--><!----><span>安装</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#installation" class="router-link-active router-link-exact-active sidebar-item" aria-label="Installation"><!--[--><!--]--><!----><span>Installation</span><!--[--><!--]--></a><ul style="" class="sidebar-item-children"><!--[--><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用包管理工具-govendor" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用包管理工具 Govendor"><!--[--><!--]--><!----><span>使用包管理工具 Govendor</span><!--[--><!--]--></a><!----></li><!--]--></ul></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#快速开始" class="router-link-active router-link-exact-active sidebar-item" aria-label="快速开始"><!--[--><!--]--><!----><span>快速开始</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#quick-start" class="router-link-active router-link-exact-active sidebar-item" aria-label="Quick start"><!--[--><!--]--><!----><span>Quick start</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#基准" class="router-link-active router-link-exact-active sidebar-item" aria-label="基准"><!--[--><!--]--><!----><span>基准</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#benchmarks" class="router-link-active router-link-exact-active sidebar-item" aria-label="Benchmarks"><!--[--><!--]--><!----><span>Benchmarks</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#gin-v1-stable" class="router-link-active router-link-exact-active sidebar-item" aria-label="Gin v1. stable"><!--[--><!--]--><!----><span>Gin v1. stable</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用-jsoniter-构建" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用 jsoniter 构建"><!--[--><!--]--><!----><span>使用 jsoniter 构建</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#build-with-jsoniter" class="router-link-active router-link-exact-active sidebar-item" aria-label="Build with jsoniter"><!--[--><!--]--><!----><span>Build with jsoniter</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#api示例" class="router-link-active router-link-exact-active sidebar-item" aria-label="API示例"><!--[--><!--]--><!----><span>API示例</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#api-examples" class="router-link-active router-link-exact-active sidebar-item" aria-label="Api examples"><!--[--><!--]--><!----><span>Api examples</span><!--[--><!--]--></a><ul style="" class="sidebar-item-children"><!--[--><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用-get-post-put-patch-delete-和-options-路由方法" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用 GET, POST, PUT, PATCH, DELETE 和 OPTIONS 路由方法"><!--[--><!--]--><!----><span>使用 GET, POST, PUT, PATCH, DELETE 和 OPTIONS 路由方法</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#using-get-post-put-patch-delete-and-options" class="router-link-active router-link-exact-active sidebar-item" aria-label="Using GET, POST, PUT, PATCH, DELETE and OPTIONS"><!--[--><!--]--><!----><span>Using GET, POST, PUT, PATCH, DELETE and OPTIONS</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#路径参数" class="router-link-active router-link-exact-active sidebar-item" aria-label="路径参数"><!--[--><!--]--><!----><span>路径参数</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#parameters-in-path" class="router-link-active router-link-exact-active sidebar-item" aria-label="Parameters in path"><!--[--><!--]--><!----><span>Parameters in path</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#查询字符串参数" class="router-link-active router-link-exact-active sidebar-item" aria-label="查询字符串参数"><!--[--><!--]--><!----><span>查询字符串参数</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#querystring-parameters" class="router-link-active router-link-exact-active sidebar-item" aria-label="Querystring parameters"><!--[--><!--]--><!----><span>Querystring parameters</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#multipart-urlencoded-表单" class="router-link-active router-link-exact-active sidebar-item" aria-label="Multipart/Urlencoded 表单"><!--[--><!--]--><!----><span>Multipart/Urlencoded 表单</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#multipart-urlencoded-form" class="router-link-active router-link-exact-active sidebar-item" aria-label="Multipart/Urlencoded Form"><!--[--><!--]--><!----><span>Multipart/Urlencoded Form</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#其他示例-查询-表单" class="router-link-active router-link-exact-active sidebar-item" aria-label="其他示例: 查询 + 表单"><!--[--><!--]--><!----><span>其他示例: 查询 + 表单</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#another-example-query-post-form" class="router-link-active router-link-exact-active sidebar-item" aria-label="Another example: query + post form"><!--[--><!--]--><!----><span>Another example: query + post form</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#以映射表示的查询字符串或者表单参数" class="router-link-active router-link-exact-active sidebar-item" aria-label="以映射表示的查询字符串或者表单参数"><!--[--><!--]--><!----><span>以映射表示的查询字符串或者表单参数</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#map-as-querystring-or-postform-parameters" class="router-link-active router-link-exact-active sidebar-item" aria-label="Map as querystring or postform parameters"><!--[--><!--]--><!----><span>Map as querystring or postform parameters</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#上传文件" class="router-link-active router-link-exact-active sidebar-item" aria-label="上传文件"><!--[--><!--]--><!----><span>上传文件</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#upload-files" class="router-link-active router-link-exact-active sidebar-item" aria-label="Upload files"><!--[--><!--]--><!----><span>Upload files</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#分组路由" class="router-link-active router-link-exact-active sidebar-item" aria-label="分组路由"><!--[--><!--]--><!----><span>分组路由</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#grouping-routes" class="router-link-active router-link-exact-active sidebar-item" aria-label="Grouping routes"><!--[--><!--]--><!----><span>Grouping routes</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#无中间件路由" class="router-link-active router-link-exact-active sidebar-item" aria-label="无中间件路由"><!--[--><!--]--><!----><span>无中间件路由</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#blank-gin-without-middleware-by-default" class="router-link-active router-link-exact-active sidebar-item" aria-label="Blank Gin without middleware by default"><!--[--><!--]--><!----><span>Blank Gin without middleware by default</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用中间件" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用中间件"><!--[--><!--]--><!----><span>使用中间件</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#using-middleware" class="router-link-active router-link-exact-active sidebar-item" aria-label="Using middleware"><!--[--><!--]--><!----><span>Using middleware</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#如何写日志" class="router-link-active router-link-exact-active sidebar-item" aria-label="如何写日志"><!--[--><!--]--><!----><span>如何写日志</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#how-to-write-log-file" class="router-link-active router-link-exact-active sidebar-item" aria-label="How to write log file"><!--[--><!--]--><!----><span>How to write log file</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#自定义-log-format" class="router-link-active router-link-exact-active sidebar-item" aria-label="自定义 log format"><!--[--><!--]--><!----><span>自定义 log format</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#custom-log-format" class="router-link-active router-link-exact-active sidebar-item" aria-label="Custom log format"><!--[--><!--]--><!----><span>Custom log format</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#controlling-log-output-coloring" class="router-link-active router-link-exact-active sidebar-item" aria-label="Controlling Log output coloring"><!--[--><!--]--><!----><span>Controlling Log output coloring</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#模型绑定与验证" class="router-link-active router-link-exact-active sidebar-item" aria-label="模型绑定与验证"><!--[--><!--]--><!----><span>模型绑定与验证</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#model-binding-and-validation" class="router-link-active router-link-exact-active sidebar-item" aria-label="Model binding and validation"><!--[--><!--]--><!----><span>Model binding and validation</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#自定义验证器" class="router-link-active router-link-exact-active sidebar-item" aria-label="自定义验证器"><!--[--><!--]--><!----><span>自定义验证器</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#custom-validators" class="router-link-active router-link-exact-active sidebar-item" aria-label="Custom Validators"><!--[--><!--]--><!----><span>Custom Validators</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#只绑定查询字符串" class="router-link-active router-link-exact-active sidebar-item" aria-label="只绑定查询字符串"><!--[--><!--]--><!----><span>只绑定查询字符串</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#only-bind-query-string" class="router-link-active router-link-exact-active sidebar-item" aria-label="Only Bind Query String"><!--[--><!--]--><!----><span>Only Bind Query String</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#绑定查询字符串或者-post-data" class="router-link-active router-link-exact-active sidebar-item" aria-label="绑定查询字符串或者 Post Data"><!--[--><!--]--><!----><span>绑定查询字符串或者 Post Data</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#bind-query-string-or-post-data" class="router-link-active router-link-exact-active sidebar-item" aria-label="Bind Query String or Post Data"><!--[--><!--]--><!----><span>Bind Query String or Post Data</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#绑定-uri" class="router-link-active router-link-exact-active sidebar-item" aria-label="绑定 Uri"><!--[--><!--]--><!----><span>绑定 Uri</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#bind-uri" class="router-link-active router-link-exact-active sidebar-item" aria-label="Bind Uri"><!--[--><!--]--><!----><span>Bind Uri</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#绑定-header" class="router-link-active router-link-exact-active sidebar-item" aria-label="绑定 Header"><!--[--><!--]--><!----><span>绑定 Header</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#bind-header" class="router-link-active router-link-exact-active sidebar-item" aria-label="Bind Header"><!--[--><!--]--><!----><span>Bind Header</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#绑定-html-复选框" class="router-link-active router-link-exact-active sidebar-item" aria-label="绑定 HTML 复选框"><!--[--><!--]--><!----><span>绑定 HTML 复选框</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#bind-html-checkboxes" class="router-link-active router-link-exact-active sidebar-item" aria-label="Bind HTML checkboxes"><!--[--><!--]--><!----><span>Bind HTML checkboxes</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#multipart-urlencoded-表单绑定" class="router-link-active router-link-exact-active sidebar-item" aria-label="Multipart/Urlencoded 表单绑定"><!--[--><!--]--><!----><span>Multipart/Urlencoded 表单绑定</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#multipart-urlencoded-binding" class="router-link-active router-link-exact-active sidebar-item" aria-label="Multipart/Urlencoded binding"><!--[--><!--]--><!----><span>Multipart/Urlencoded binding</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#xml-json-yaml-and-protobuf-渲染" class="router-link-active router-link-exact-active sidebar-item" aria-label="XML, JSON, YAML and ProtoBuf 渲染"><!--[--><!--]--><!----><span>XML, JSON, YAML and ProtoBuf 渲染</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#xml-json-yaml-and-protobuf-rendering" class="router-link-active router-link-exact-active sidebar-item" aria-label="XML, JSON, YAML and ProtoBuf rendering"><!--[--><!--]--><!----><span>XML, JSON, YAML and ProtoBuf rendering</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#提供静态文件" class="router-link-active router-link-exact-active sidebar-item" aria-label="提供静态文件"><!--[--><!--]--><!----><span>提供静态文件</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#serving-static-files" class="router-link-active router-link-exact-active sidebar-item" aria-label="Serving static files"><!--[--><!--]--><!----><span>Serving static files</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#serving-data-from-reader" class="router-link-active router-link-exact-active sidebar-item" aria-label="Serving data from reader"><!--[--><!--]--><!----><span>Serving data from reader</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#html-渲染" class="router-link-active router-link-exact-active sidebar-item" aria-label="HTML 渲染"><!--[--><!--]--><!----><span>HTML 渲染</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#html-rendering" class="router-link-active router-link-exact-active sidebar-item" aria-label="HTML rendering"><!--[--><!--]--><!----><span>HTML rendering</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#多模板" class="router-link-active router-link-exact-active sidebar-item" aria-label="多模板"><!--[--><!--]--><!----><span>多模板</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#multitemplate" class="router-link-active router-link-exact-active sidebar-item" aria-label="Multitemplate"><!--[--><!--]--><!----><span>Multitemplate</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#重定向" class="router-link-active router-link-exact-active sidebar-item" aria-label="重定向"><!--[--><!--]--><!----><span>重定向</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#redirects" class="router-link-active router-link-exact-active sidebar-item" aria-label="Redirects"><!--[--><!--]--><!----><span>Redirects</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#自定义中间件" class="router-link-active router-link-exact-active sidebar-item" aria-label="自定义中间件"><!--[--><!--]--><!----><span>自定义中间件</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#custom-middleware" class="router-link-active router-link-exact-active sidebar-item" aria-label="Custom Middleware"><!--[--><!--]--><!----><span>Custom Middleware</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用-basicauth-中间件" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用 BasicAuth() 中间件"><!--[--><!--]--><!----><span>使用 BasicAuth() 中间件</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#using-basicauth-middleware" class="router-link-active router-link-exact-active sidebar-item" aria-label="Using BasicAuth middleware"><!--[--><!--]--><!----><span>Using BasicAuth middleware</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#中间件中的协程" class="router-link-active router-link-exact-active sidebar-item" aria-label="中间件中的协程"><!--[--><!--]--><!----><span>中间件中的协程</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#goroutines-inside-a-middleware" class="router-link-active router-link-exact-active sidebar-item" aria-label="Goroutines inside a middleware"><!--[--><!--]--><!----><span>Goroutines inside a middleware</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#自定义-http-配置" class="router-link-active router-link-exact-active sidebar-item" aria-label="自定义 HTTP 配置"><!--[--><!--]--><!----><span>自定义 HTTP 配置</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#custom-http-configuration" class="router-link-active router-link-exact-active sidebar-item" aria-label="Custom HTTP configuration"><!--[--><!--]--><!----><span>Custom HTTP configuration</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#support-let-s-encrypt" class="router-link-active router-link-exact-active sidebar-item" aria-label="Support Let&#39;s Encrypt"><!--[--><!--]--><!----><span>Support Let&#39;s Encrypt</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用-gin-运行多服务" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用 Gin 运行多服务"><!--[--><!--]--><!----><span>使用 Gin 运行多服务</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#run-multiple-service-using-gin" class="router-link-active router-link-exact-active sidebar-item" aria-label="Run multiple service using Gin"><!--[--><!--]--><!----><span>Run multiple service using Gin</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#优雅重启或停止" class="router-link-active router-link-exact-active sidebar-item" aria-label="优雅重启或停止"><!--[--><!--]--><!----><span>优雅重启或停止</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#graceful-restart-or-stop" class="router-link-active router-link-exact-active sidebar-item" aria-label="Graceful restart or stop"><!--[--><!--]--><!----><span>Graceful restart or stop</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#将服务器构建为一个包含模板文件的二进制文件" class="router-link-active router-link-exact-active sidebar-item" aria-label="将服务器构建为一个包含模板文件的二进制文件"><!--[--><!--]--><!----><span>将服务器构建为一个包含模板文件的二进制文件</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#build-a-single-binary-with-templates" class="router-link-active router-link-exact-active sidebar-item" aria-label="Build a single binary with templates"><!--[--><!--]--><!----><span>Build a single binary with templates</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#使用自定义结构绑定表单数据" class="router-link-active router-link-exact-active sidebar-item" aria-label="使用自定义结构绑定表单数据"><!--[--><!--]--><!----><span>使用自定义结构绑定表单数据</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#bind-form-data-request-with-custom-struct" class="router-link-active router-link-exact-active sidebar-item" aria-label="Bind form-data request with custom struct"><!--[--><!--]--><!----><span>Bind form-data request with custom struct</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#尝试将-body-绑定到不同的结构中" class="router-link-active router-link-exact-active sidebar-item" aria-label="尝试将 body 绑定到不同的结构中"><!--[--><!--]--><!----><span>尝试将 body 绑定到不同的结构中</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#try-to-bind-body-into-different-structs" class="router-link-active router-link-exact-active sidebar-item" aria-label="Try to bind body into different structs"><!--[--><!--]--><!----><span>Try to bind body into different structs</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#http2-server-push" class="router-link-active router-link-exact-active sidebar-item" aria-label="http2 server push"><!--[--><!--]--><!----><span>http2 server push</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#http2-server-push-1" class="router-link-active router-link-exact-active sidebar-item" aria-label="http2 server push"><!--[--><!--]--><!----><span>http2 server push</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#定义路由日志记录格式" class="router-link-active router-link-exact-active sidebar-item" aria-label="定义路由日志记录格式"><!--[--><!--]--><!----><span>定义路由日志记录格式</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#define-format-for-the-log-of-routes" class="router-link-active router-link-exact-active sidebar-item" aria-label="Define format for the log of routes"><!--[--><!--]--><!----><span>Define format for the log of routes</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#set-and-get-a-cookie" class="router-link-active router-link-exact-active sidebar-item" aria-label="Set and get a cookie"><!--[--><!--]--><!----><span>Set and get a cookie</span><!--[--><!--]--></a><!----></li><!--]--></ul></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#testing" class="router-link-active router-link-exact-active sidebar-item" aria-label="Testing"><!--[--><!--]--><!----><span>Testing</span><!--[--><!--]--></a><!----></li><li><a aria-current="page" href="/posts/2023/4/docs/Gin/#users" class="router-link-active router-link-exact-active sidebar-item" aria-label="Users"><!--[--><!--]--><!----><span>Users</span><!--[--><!--]--></a><!----></li><!--]--></ul></li><!--]--></ul><!--[--><!--]--></aside><!--]--><div class="page-content"><!--[--><main class="page"><!--[--><div class="article-header" style=""><!----><div class="article-header-content"><!----><h1 class="article-title"></h1><!----><div class="article-icons"><div class="article-icon"><svg class="ov-icon" style="font-size:1.08em;" aria-hidden="true" width="17.28" height="17.28" viewbox="-75.52 -43.52 599.04 599.04" fill="currentColor"><path d="M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z"/></svg><span>科科人神</span></div><!----><div class="article-icon"><svg class="ov-icon" style="font-size:1.08em;" aria-hidden="true" width="17.28" height="17.28" viewbox="0 0 24 24" fill="currentColor"><path fill="none" d="M0 0h24v24H0z"/><path d="M17.618 5.968l1.453-1.453 1.414 1.414-1.453 1.453a9 9 0 11-1.414-1.414zM12 20a7 7 0 100-14 7 7 0 000 14zM11 8h2v6h-2V8zM8 1h8v2H8V1z"/></svg><span>46 min</span></div></div></div><!----></div><!--[--><!--]--><!--]--><div class="theme-gungnir-content"><!--[--><!--]--><!--[--><h1 id="gin-中文文档" tabindex="-1"><a class="header-anchor" href="#gin-中文文档" aria-hidden="true">#</a> Gin 中文文档</h1><p>Gin 中文文档，本文档基于 <a href="https://github.com/gin-gonic/gin" target="_blank" rel="noopener noreferrer">Gin</a> 官方文档。不定期更新。</p><img align="right" width="159px" src="https://raw.githubusercontent.com/gin-gonic/logo/master/color.png"><p><a href="https://travis-ci.org/gin-gonic/gin" target="_blank" rel="noopener noreferrer"><img src="https://travis-ci.org/gin-gonic/gin.svg" alt="Build Status"></a><a href="https://codecov.io/gh/gin-gonic/gin" target="_blank" rel="noopener noreferrer"><img src="https://codecov.io/gh/gin-gonic/gin/branch/master/graph/badge.svg" alt="codecov"></a><a href="https://goreportcard.com/report/github.com/gin-gonic/gin" target="_blank" rel="noopener noreferrer"><img src="https://goreportcard.com/badge/github.com/gin-gonic/gin" alt="Go Report Card"></a><a href="https://godoc.org/github.com/gin-gonic/gin" target="_blank" rel="noopener noreferrer"><img src="https://godoc.org/github.com/gin-gonic/gin?status.svg" alt="GoDoc"></a><a href="https://gitter.im/gin-gonic/gin?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge" target="_blank" rel="noopener noreferrer"><img src="https://badges.gitter.im/Join Chat.svg" alt="Join the chat at https://gitter.im/gin-gonic/gin"></a><a href="https://sourcegraph.com/github.com/gin-gonic/gin?badge" target="_blank" rel="noopener noreferrer"><img src="https://sourcegraph.com/github.com/gin-gonic/gin/-/badge.svg" alt="Sourcegraph"></a><a href="https://www.codetriage.com/gin-gonic/gin" target="_blank" rel="noopener noreferrer"><img src="https://www.codetriage.com/gin-gonic/gin/badges/users.svg" alt="Open Source Helpers"></a><a href="https://github.com/gin-gonic/gin/releases" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/github/release/gin-gonic/gin.svg?style=flat-square" alt="Release"></a></p><p>Gin 是一个使用 Go 语言写的 web 框架.它拥有与 Martini 相似的 API,但它比 Martini 快 40 多倍。Gin 内部使用 Golang 最快的 HTTP 路由器 <a href="https://github.com/julienschmidt/httprouter" target="_blank" rel="noopener noreferrer">httprouter</a>。如果你需要更高的性能,更快的开发效率,你会喜欢上 Gin。</p><h2 id="contents" tabindex="-1"><a class="header-anchor" href="#contents" aria-hidden="true">#</a> Contents</h2><ul><li><a href="#installation">安装</a></li><li><a href="#quick-start">快速开始</a></li><li><a href="#benchmarks">基准</a></li><li><a href="#gin-v1-stable">Gin v1.stable</a></li><li><a href="#build-with-jsoniter">使用 jsoniter 构建</a></li><li><a href="#api-examples">API 示例</a><ul><li><a href="#using-get-post-put-patch-delete-and-options">使用 GET,POST,PUT,PATCH,DELETE 和 OPTIONS 方法</a></li><li><a href="#parameters-in-path">路径参数</a></li><li><a href="#querystring-parameters">Querystring parameters</a></li><li><a href="#multiparturlencoded-form">Multipart/Urlencoded Form</a></li><li><a href="#another-example-query--post-form">Another example: query + post form</a></li><li><a href="#map-as-querystring-or-postform-parameters">Map as querystring or postform parameters</a></li><li><a href="#upload-files">Upload files</a></li><li><a href="#grouping-routes">Grouping routes</a></li><li><a href="#blank-gin-without-middleware-by-default">Blank Gin without middleware by default</a></li><li><a href="#using-middleware">Using middleware</a></li><li><a href="#how-to-write-log-file">How to write log file</a></li><li><a href="#custom-log-format">Custom log format</a></li><li><a href="#controlling-log-output-coloring">Controlling Log output coloring</a></li><li><a href="#model-binding-and-validation">Model binding and validation</a></li><li><a href="#custom-validators">Custom Validators</a></li><li><a href="#only-bind-query-string">Only Bind Query String</a></li><li><a href="#bind-query-string-or-post-data">Bind Query String or Post Data</a></li><li><a href="#bind-uri">Bind Uri</a></li><li><a href="#bind-header">Bind Header</a></li><li><a href="#bind-html-checkboxes">Bind HTML checkboxes</a></li><li><a href="#multiparturlencoded-binding">Multipart/Urlencoded binding</a></li><li><a href="#xml-json-yaml-and-protobuf-rendering">XML, JSON, YAML and ProtoBuf rendering</a></li><li><a href="#jsonp">JSONP rendering</a></li><li><a href="#serving-static-files">Serving static files</a></li><li><a href="#serving-data-from-reader">Serving data from reader</a></li><li><a href="#html-rendering">HTML rendering</a></li><li><a href="#multitemplate">Multitemplate</a></li><li><a href="#redirects">Redirects</a></li><li><a href="#custom-middleware">Custom Middleware</a></li><li><a href="#using-basicauth-middleware">Using BasicAuth() middleware</a></li><li><a href="#goroutines-inside-a-middleware">Goroutines inside a middleware</a></li><li><a href="#custom-http-configuration">Custom HTTP configuration</a></li><li><a href="#support-lets-encrypt">Support Let&#39;s Encrypt</a></li><li><a href="#run-multiple-service-using-gin">Run multiple service using Gin</a></li><li><a href="#graceful-restart-or-stop">Graceful restart or stop</a></li><li><a href="#build-a-single-binary-with-templates">Build a single binary with templates</a></li><li><a href="#bind-form-data-request-with-custom-struct">Bind form-data request with custom struct</a></li><li><a href="#try-to-bind-body-into-different-structs">Try to bind body into different structs</a></li><li><a href="#http2-server-push">http2 server push</a></li><li><a href="#define-format-for-the-log-of-routes">Define format for the log of routes</a></li><li><a href="#set-and-get-a-cookie">Set and get a cookie</a></li></ul></li><li><a href="#testing">Testing</a></li><li><a href="#users">Users</a></li></ul><h2 id="安装" tabindex="-1"><a class="header-anchor" href="#安装" aria-hidden="true">#</a> 安装</h2><h2 id="installation" tabindex="-1"><a class="header-anchor" href="#installation" aria-hidden="true">#</a> Installation</h2><p>安装 gin 包之前，需要先下载安装 Go 以及设置好 Go 工作空间。</p><ol><li>下载安装（Go 版本 1.10+）:</li></ol><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ go get -u github.com/gin-gonic/gin
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><ol start="2"><li>导入包:</li></ol><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><ol start="3"><li>(可选) 导入 <code>net/http</code>。 如果需要 http 包中的一些参量如 <code>http.StatusOK</code>。</li></ol><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token string">&quot;net/http&quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="使用包管理工具-govendor" tabindex="-1"><a class="header-anchor" href="#使用包管理工具-govendor" aria-hidden="true">#</a> 使用包管理工具 <a href="https://github.com/kardianos/govendor" target="_blank" rel="noopener noreferrer">Govendor</a></h3><ol><li><code>go get</code> govendor</li></ol><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ go get github.com/kardianos/govendor
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><ol start="2"><li>创建项目文件夹并进入</li></ol><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">mkdir</span> -p <span class="token variable">$GOPATH</span>/src/github.com/myusername/project <span class="token operator">&amp;&amp;</span> <span class="token builtin class-name">cd</span> <span class="token string">&quot;<span class="token variable">$_</span>&quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><ol start="3"><li>初始化你的项目并添加 gin</li></ol><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ govendor init
$ govendor fetch github.com/gin-gonic/gin@v1.3
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><ol start="4"><li>复制一个模板到项目</li></ol><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">curl</span> https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go <span class="token operator">&gt;</span> main.go
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><ol start="5"><li>启动项目</li></ol><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ go run main.go
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h2 id="快速开始" tabindex="-1"><a class="header-anchor" href="#快速开始" aria-hidden="true">#</a> 快速开始</h2><h2 id="quick-start" tabindex="-1"><a class="header-anchor" href="#quick-start" aria-hidden="true">#</a> Quick start</h2><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code><span class="token comment"># 假定下面的代码在 example.go 文件中</span>
$ <span class="token function">cat</span> example.go
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;message&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// listen and serve on 0.0.0.0:8080</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-text ext-text line-numbers-mode"><pre class="language-text"><code># 云运行 example.go 然后在浏览器访问 0.0.0.0:8080/ping
$ go run example.go
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="基准" tabindex="-1"><a class="header-anchor" href="#基准" aria-hidden="true">#</a> 基准</h2><h2 id="benchmarks" tabindex="-1"><a class="header-anchor" href="#benchmarks" aria-hidden="true">#</a> Benchmarks</h2><p>Gin 使用 <a href="https://github.com/julienschmidt/httprouter" target="_blank" rel="noopener noreferrer">HttpRouter</a> 的一个定制版本</p><p><a href="https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md" target="_blank" rel="noopener noreferrer">查看所有基准</a></p><table><thead><tr><th>Benchmark name</th><th style="text-align:right;">(1)</th><th style="text-align:right;">(2)</th><th style="text-align:right;">(3)</th><th style="text-align:right;">(4)</th></tr></thead><tbody><tr><td><strong>BenchmarkGin_GithubAll</strong></td><td style="text-align:right;"><strong>30000</strong></td><td style="text-align:right;"><strong>48375</strong></td><td style="text-align:right;"><strong>0</strong></td><td style="text-align:right;"><strong>0</strong></td></tr><tr><td>BenchmarkAce_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">134059</td><td style="text-align:right;">13792</td><td style="text-align:right;">167</td></tr><tr><td>BenchmarkBear_GithubAll</td><td style="text-align:right;">5000</td><td style="text-align:right;">534445</td><td style="text-align:right;">86448</td><td style="text-align:right;">943</td></tr><tr><td>BenchmarkBeego_GithubAll</td><td style="text-align:right;">3000</td><td style="text-align:right;">592444</td><td style="text-align:right;">74705</td><td style="text-align:right;">812</td></tr><tr><td>BenchmarkBone_GithubAll</td><td style="text-align:right;">200</td><td style="text-align:right;">6957308</td><td style="text-align:right;">698784</td><td style="text-align:right;">8453</td></tr><tr><td>BenchmarkDenco_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">158819</td><td style="text-align:right;">20224</td><td style="text-align:right;">167</td></tr><tr><td>BenchmarkEcho_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">154700</td><td style="text-align:right;">6496</td><td style="text-align:right;">203</td></tr><tr><td>BenchmarkGocraftWeb_GithubAll</td><td style="text-align:right;">3000</td><td style="text-align:right;">570806</td><td style="text-align:right;">131656</td><td style="text-align:right;">1686</td></tr><tr><td>BenchmarkGoji_GithubAll</td><td style="text-align:right;">2000</td><td style="text-align:right;">818034</td><td style="text-align:right;">56112</td><td style="text-align:right;">334</td></tr><tr><td>BenchmarkGojiv2_GithubAll</td><td style="text-align:right;">2000</td><td style="text-align:right;">1213973</td><td style="text-align:right;">274768</td><td style="text-align:right;">3712</td></tr><tr><td>BenchmarkGoJsonRest_GithubAll</td><td style="text-align:right;">2000</td><td style="text-align:right;">785796</td><td style="text-align:right;">134371</td><td style="text-align:right;">2737</td></tr><tr><td>BenchmarkGoRestful_GithubAll</td><td style="text-align:right;">300</td><td style="text-align:right;">5238188</td><td style="text-align:right;">689672</td><td style="text-align:right;">4519</td></tr><tr><td>BenchmarkGorillaMux_GithubAll</td><td style="text-align:right;">100</td><td style="text-align:right;">10257726</td><td style="text-align:right;">211840</td><td style="text-align:right;">2272</td></tr><tr><td>BenchmarkHttpRouter_GithubAll</td><td style="text-align:right;">20000</td><td style="text-align:right;">105414</td><td style="text-align:right;">13792</td><td style="text-align:right;">167</td></tr><tr><td>BenchmarkHttpTreeMux_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">319934</td><td style="text-align:right;">65856</td><td style="text-align:right;">671</td></tr><tr><td>BenchmarkKocha_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">209442</td><td style="text-align:right;">23304</td><td style="text-align:right;">843</td></tr><tr><td>BenchmarkLARS_GithubAll</td><td style="text-align:right;">20000</td><td style="text-align:right;">62565</td><td style="text-align:right;">0</td><td style="text-align:right;">0</td></tr><tr><td>BenchmarkMacaron_GithubAll</td><td style="text-align:right;">2000</td><td style="text-align:right;">1161270</td><td style="text-align:right;">204194</td><td style="text-align:right;">2000</td></tr><tr><td>BenchmarkMartini_GithubAll</td><td style="text-align:right;">200</td><td style="text-align:right;">9991713</td><td style="text-align:right;">226549</td><td style="text-align:right;">2325</td></tr><tr><td>BenchmarkPat_GithubAll</td><td style="text-align:right;">200</td><td style="text-align:right;">5590793</td><td style="text-align:right;">1499568</td><td style="text-align:right;">27435</td></tr><tr><td>BenchmarkPossum_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">319768</td><td style="text-align:right;">84448</td><td style="text-align:right;">609</td></tr><tr><td>BenchmarkR2router_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">305134</td><td style="text-align:right;">77328</td><td style="text-align:right;">979</td></tr><tr><td>BenchmarkRivet_GithubAll</td><td style="text-align:right;">10000</td><td style="text-align:right;">132134</td><td style="text-align:right;">16272</td><td style="text-align:right;">167</td></tr><tr><td>BenchmarkTango_GithubAll</td><td style="text-align:right;">3000</td><td style="text-align:right;">552754</td><td style="text-align:right;">63826</td><td style="text-align:right;">1618</td></tr><tr><td>BenchmarkTigerTonic_GithubAll</td><td style="text-align:right;">1000</td><td style="text-align:right;">1439483</td><td style="text-align:right;">239104</td><td style="text-align:right;">5374</td></tr><tr><td>BenchmarkTraffic_GithubAll</td><td style="text-align:right;">100</td><td style="text-align:right;">11383067</td><td style="text-align:right;">2659329</td><td style="text-align:right;">21848</td></tr><tr><td>BenchmarkVulcan_GithubAll</td><td style="text-align:right;">5000</td><td style="text-align:right;">394253</td><td style="text-align:right;">19894</td><td style="text-align:right;">609</td></tr></tbody></table><ul><li>(1): 持续时间达到的总重复次数越多，意味着结果越好</li><li>(2): 单次重复持续时间（ns / op）越低越好</li><li>(3): 堆内存（B / op）越低越好</li><li>(4): 平均每次重复分配 (allocs/op) 越低越好</li></ul><h2 id="gin-v1-stable" tabindex="-1"><a class="header-anchor" href="#gin-v1-stable" aria-hidden="true">#</a> Gin v1. stable</h2><ul><li>[x] Zero allocation router.</li><li>[x] Still the fastest http router and framework. From routing to writing.</li><li>[x] Complete suite of unit tests</li><li>[x] Battle tested</li><li>[x] API frozen, new releases will not break your code.</li></ul><h2 id="使用-jsoniter-构建" tabindex="-1"><a class="header-anchor" href="#使用-jsoniter-构建" aria-hidden="true">#</a> 使用 <a href="https://github.com/json-iterator/go" target="_blank" rel="noopener noreferrer">jsoniter</a> 构建</h2><h2 id="build-with-jsoniter" tabindex="-1"><a class="header-anchor" href="#build-with-jsoniter" aria-hidden="true">#</a> Build with <a href="https://github.com/json-iterator/go" target="_blank" rel="noopener noreferrer">jsoniter</a></h2><p>Gin 使用 <code>encoding/json</code> 作为默认的 json 解析器但你可以构建时指定成 <a href="https://github.com/json-iterator/go" target="_blank" rel="noopener noreferrer">jsoniter</a></p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ go build -tags<span class="token operator">=</span>jsoniter <span class="token builtin class-name">.</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h2 id="api示例" tabindex="-1"><a class="header-anchor" href="#api示例" aria-hidden="true">#</a> API示例</h2><h2 id="api-examples" tabindex="-1"><a class="header-anchor" href="#api-examples" aria-hidden="true">#</a> Api examples</h2><h3 id="使用-get-post-put-patch-delete-和-options-路由方法" tabindex="-1"><a class="header-anchor" href="#使用-get-post-put-patch-delete-和-options-路由方法" aria-hidden="true">#</a> 使用 GET, POST, PUT, PATCH, DELETE 和 OPTIONS 路由方法</h3><h3 id="using-get-post-put-patch-delete-and-options" tabindex="-1"><a class="header-anchor" href="#using-get-post-put-patch-delete-and-options" aria-hidden="true">#</a> Using GET, POST, PUT, PATCH, DELETE and OPTIONS</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// 禁用控制台颜色</span>
	<span class="token comment">// gin.DisableConsoleColor()</span>

	<span class="token comment">// 用默认的中间件创建一个gin路由器:</span>
	<span class="token comment">// logger and recovery (crash-free) middleware</span>
	<span class="token comment">// 包含日志和恢复(不崩溃)中间件</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someGet&quot;</span><span class="token punctuation">,</span> getting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/somePost&quot;</span><span class="token punctuation">,</span> posting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">PUT</span><span class="token punctuation">(</span><span class="token string">&quot;/somePut&quot;</span><span class="token punctuation">,</span> putting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">DELETE</span><span class="token punctuation">(</span><span class="token string">&quot;/someDelete&quot;</span><span class="token punctuation">,</span> deleting<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">PATCH</span><span class="token punctuation">(</span><span class="token string">&quot;/somePatch&quot;</span><span class="token punctuation">,</span> patching<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">HEAD</span><span class="token punctuation">(</span><span class="token string">&quot;/someHead&quot;</span><span class="token punctuation">,</span> head<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">OPTIONS</span><span class="token punctuation">(</span><span class="token string">&quot;/someOptions&quot;</span><span class="token punctuation">,</span> options<span class="token punctuation">)</span>

	<span class="token comment">// By default it serves on :8080 unless a</span>
	<span class="token comment">// PORT environment variable was defined.</span>
	<span class="token comment">// 默认监听8080端口，除非指定了PORT环境变量</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// router.Run(&quot;:3000&quot;) 指定端口号为 :3000</span>

<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="路径参数" tabindex="-1"><a class="header-anchor" href="#路径参数" aria-hidden="true">#</a> 路径参数</h3><h3 id="parameters-in-path" tabindex="-1"><a class="header-anchor" href="#parameters-in-path" aria-hidden="true">#</a> Parameters in path</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 路由1 匹配 /user/john,但是不匹配 /user/ 或 /user</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/user/:name&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		name <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Param</span><span class="token punctuation">(</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;Hello %s&quot;</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>


	<span class="token comment">// 路由2 这个会匹配 /user/john/ 和 /user/john/send</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/user/:name/*action&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		name <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Param</span><span class="token punctuation">(</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span>
		action <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Param</span><span class="token punctuation">(</span><span class="token string">&quot;action&quot;</span><span class="token punctuation">)</span>
		message <span class="token operator">:=</span> name <span class="token operator">+</span> <span class="token string">&quot; is &quot;</span> <span class="token operator">+</span> action
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> message<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// 注意 /user/:name 和 /user/:name/是俩个完全不同的路由</span>

	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="查询字符串参数" tabindex="-1"><a class="header-anchor" href="#查询字符串参数" aria-hidden="true">#</a> 查询字符串参数</h3><h3 id="querystring-parameters" tabindex="-1"><a class="header-anchor" href="#querystring-parameters" aria-hidden="true">#</a> Querystring parameters</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 查询字符串参数通过解析基础请求对象获得</span>
	<span class="token comment">// 请求响应匹配url:  /welcome?firstname=Jane&amp;lastname=Doe</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/welcome&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	    <span class="token comment">// 取firstname的值,不存在则设为Guest</span>
		firstname <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">DefaultQuery</span><span class="token punctuation">(</span><span class="token string">&quot;firstname&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;Guest&quot;</span><span class="token punctuation">)</span>
		lastname <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Query</span><span class="token punctuation">(</span><span class="token string">&quot;lastname&quot;</span><span class="token punctuation">)</span> <span class="token comment">// shortcut for c.Request.URL.Query().Get(&quot;lastname&quot;)</span>

		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;Hello %s %s&quot;</span><span class="token punctuation">,</span> firstname<span class="token punctuation">,</span> lastname<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="multipart-urlencoded-表单" tabindex="-1"><a class="header-anchor" href="#multipart-urlencoded-表单" aria-hidden="true">#</a> Multipart/Urlencoded 表单</h3><h3 id="multipart-urlencoded-form" tabindex="-1"><a class="header-anchor" href="#multipart-urlencoded-form" aria-hidden="true">#</a> Multipart/Urlencoded Form</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/form_post&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		message <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">)</span>
		nick <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">DefaultPostForm</span><span class="token punctuation">(</span><span class="token string">&quot;nick&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;anonymous&quot;</span><span class="token punctuation">)</span>

		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span>  <span class="token string">&quot;posted&quot;</span><span class="token punctuation">,</span>
			<span class="token string">&quot;message&quot;</span><span class="token punctuation">:</span> message<span class="token punctuation">,</span>
			<span class="token string">&quot;nick&quot;</span><span class="token punctuation">:</span>    nick<span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="其他示例-查询-表单" tabindex="-1"><a class="header-anchor" href="#其他示例-查询-表单" aria-hidden="true">#</a> 其他示例: 查询 + 表单</h3><h3 id="another-example-query-post-form" tabindex="-1"><a class="header-anchor" href="#another-example-query-post-form" aria-hidden="true">#</a> Another example: query + post form</h3><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>POST /post?id<span class="token operator">=</span><span class="token number">1234</span><span class="token operator">&amp;</span><span class="token assign-left variable">page</span><span class="token operator">=</span><span class="token number">1</span> HTTP/1.1
Content-Type: application/x-www-form-urlencoded

<span class="token assign-left variable">name</span><span class="token operator">=</span>manu<span class="token operator">&amp;</span><span class="token assign-left variable">message</span><span class="token operator">=</span>this_is_great
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/post&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// url 中查询数据</span>
		id <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Query</span><span class="token punctuation">(</span><span class="token string">&quot;id&quot;</span><span class="token punctuation">)</span>
		page <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">DefaultQuery</span><span class="token punctuation">(</span><span class="token string">&quot;page&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;0&quot;</span><span class="token punctuation">)</span>

		<span class="token comment">// post 表单中数据</span>
		name <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">)</span>
		message <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostForm</span><span class="token punctuation">(</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">)</span>

		fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;id: %s; page: %s; name: %s; message: %s&quot;</span><span class="token punctuation">,</span> id<span class="token punctuation">,</span> page<span class="token punctuation">,</span> name<span class="token punctuation">,</span> message<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>id: <span class="token number">1234</span><span class="token punctuation">;</span> page: <span class="token number">1</span><span class="token punctuation">;</span> name: manu<span class="token punctuation">;</span> message: this_is_great
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="以映射表示的查询字符串或者表单参数" tabindex="-1"><a class="header-anchor" href="#以映射表示的查询字符串或者表单参数" aria-hidden="true">#</a> 以映射表示的查询字符串或者表单参数</h3><h3 id="map-as-querystring-or-postform-parameters" tabindex="-1"><a class="header-anchor" href="#map-as-querystring-or-postform-parameters" aria-hidden="true">#</a> Map as querystring or postform parameters</h3><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>POST /post?ids<span class="token punctuation">[</span>a<span class="token punctuation">]</span><span class="token operator">=</span><span class="token number">1234</span><span class="token operator">&amp;</span>ids<span class="token punctuation">[</span>b<span class="token punctuation">]</span><span class="token operator">=</span>hello HTTP/1.1
Content-Type: application/x-www-form-urlencoded

names<span class="token punctuation">[</span>first<span class="token punctuation">]</span><span class="token operator">=</span>thinkerou<span class="token operator">&amp;</span>names<span class="token punctuation">[</span>second<span class="token punctuation">]</span><span class="token operator">=</span>tianou
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/post&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>

		ids <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">QueryMap</span><span class="token punctuation">(</span><span class="token string">&quot;ids&quot;</span><span class="token punctuation">)</span>
		names <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">PostFormMap</span><span class="token punctuation">(</span><span class="token string">&quot;names&quot;</span><span class="token punctuation">)</span>

		fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;ids: %v; names: %v&quot;</span><span class="token punctuation">,</span> ids<span class="token punctuation">,</span> names<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>ids: map<span class="token punctuation">[</span>b:hello a:1234<span class="token punctuation">]</span>, names: map<span class="token punctuation">[</span>second:tianou first:thinkerou<span class="token punctuation">]</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="上传文件" tabindex="-1"><a class="header-anchor" href="#上传文件" aria-hidden="true">#</a> 上传文件</h3><h3 id="upload-files" tabindex="-1"><a class="header-anchor" href="#upload-files" aria-hidden="true">#</a> Upload files</h3><h4 id="单个文件" tabindex="-1"><a class="header-anchor" href="#单个文件" aria-hidden="true">#</a> 单个文件</h4><p>参考问题 <a href="https://github.com/gin-gonic/gin/issues/774" target="_blank" rel="noopener noreferrer">#774</a> 和细节 <a href="examples/upload-file/single">example code</a>.</p><p><code>file.Filename</code> <strong>是不可信的</strong>。 查看 <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives" target="_blank" rel="noopener noreferrer">MDN <code>Content-Disposition</code></a> 和 <a href="https://github.com/gin-gonic/gin/issues/1693" target="_blank" rel="noopener noreferrer">#1693</a></p><blockquote><p>filename 总是可选的，应用程序不能盲目地使用它：应该删除路径信息，并执行到服务器文件系统规则的转换。</p></blockquote><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 设置可以上传 multipart 表单的最大体积（默认为 32MiB）</span>
	<span class="token comment">// router.MaxMultipartMemory = 8 &lt;&lt; 20  // 8 MiB</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/upload&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// single file</span>
		file<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">FormFile</span><span class="token punctuation">(</span><span class="token string">&quot;file&quot;</span><span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span>

		<span class="token comment">// 复制文件到指定目标</span>
		<span class="token comment">// c.SaveUploadedFile(file, dst)</span>

		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">&quot;&#39;%s&#39; uploaded!&quot;</span><span class="token punctuation">,</span> file<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>使用 <code>curl</code>:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code><span class="token function">curl</span> -X POST http://localhost:8080/upload <span class="token punctuation">\</span>
  -F <span class="token string">&quot;file=@/Users/appleboy/test.zip&quot;</span> <span class="token punctuation">\</span>
  -H <span class="token string">&quot;Content-Type: multipart/form-data&quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="多个文件" tabindex="-1"><a class="header-anchor" href="#多个文件" aria-hidden="true">#</a> 多个文件</h4><p>查看细节 <a href="https://github.com/gin-gonic/examples/tree/master/upload-file/multiple" target="_blank" rel="noopener noreferrer">example code</a>.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token comment">// 设置可以上传 multipart 表单的最大体积（默认为 32MiB）</span>
	<span class="token comment">// router.MaxMultipartMemory = 8 &lt;&lt; 20  // 8 MiB</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/upload&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// Multipart form</span>
		form<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">MultipartForm</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		files <span class="token operator">:=</span> form<span class="token punctuation">.</span>File<span class="token punctuation">[</span><span class="token string">&quot;upload[]&quot;</span><span class="token punctuation">]</span>

		<span class="token keyword">for</span> <span class="token boolean">_</span><span class="token punctuation">,</span> file <span class="token operator">:=</span> <span class="token keyword">range</span> files <span class="token punctuation">{</span>
			log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span>

			<span class="token comment">// Upload the file to specific dst.</span>
			<span class="token comment">// c.SaveUploadedFile(file, dst)</span>
		<span class="token punctuation">}</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">&quot;%d files uploaded!&quot;</span><span class="token punctuation">,</span> <span class="token function">len</span><span class="token punctuation">(</span>files<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>使用 <code>curl</code>:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code><span class="token function">curl</span> -X POST http://localhost:8080/upload <span class="token punctuation">\</span>
  -F <span class="token string">&quot;upload[]=@/Users/appleboy/test1.zip&quot;</span> <span class="token punctuation">\</span>
  -F <span class="token string">&quot;upload[]=@/Users/appleboy/test2.zip&quot;</span> <span class="token punctuation">\</span>
  -H <span class="token string">&quot;Content-Type: multipart/form-data&quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="分组路由" tabindex="-1"><a class="header-anchor" href="#分组路由" aria-hidden="true">#</a> 分组路由</h3><h3 id="grouping-routes" tabindex="-1"><a class="header-anchor" href="#grouping-routes" aria-hidden="true">#</a> Grouping routes</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Simple group: v1</span>
	v1 <span class="token operator">:=</span> router<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">&quot;/v1&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		v1<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/login&quot;</span><span class="token punctuation">,</span> loginEndpoint<span class="token punctuation">)</span>
		v1<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/submit&quot;</span><span class="token punctuation">,</span> submitEndpoint<span class="token punctuation">)</span>
		v1<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/read&quot;</span><span class="token punctuation">,</span> readEndpoint<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>

	<span class="token comment">// Simple group: v2</span>
	v2 <span class="token operator">:=</span> router<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">&quot;/v2&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		v2<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/login&quot;</span><span class="token punctuation">,</span> loginEndpoint<span class="token punctuation">)</span>
		v2<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/submit&quot;</span><span class="token punctuation">,</span> submitEndpoint<span class="token punctuation">)</span>
		v2<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/read&quot;</span><span class="token punctuation">,</span> readEndpoint<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>

	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="无中间件路由" tabindex="-1"><a class="header-anchor" href="#无中间件路由" aria-hidden="true">#</a> 无中间件路由</h3><h3 id="blank-gin-without-middleware-by-default" tabindex="-1"><a class="header-anchor" href="#blank-gin-without-middleware-by-default" aria-hidden="true">#</a> Blank Gin without middleware by default</h3><p>使用</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code>r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>而不是</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token comment">// 默认情况已启用了 log 和恢复中间件</span>
r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="使用中间件" tabindex="-1"><a class="header-anchor" href="#使用中间件" aria-hidden="true">#</a> 使用中间件</h3><h3 id="using-middleware" tabindex="-1"><a class="header-anchor" href="#using-middleware" aria-hidden="true">#</a> Using middleware</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token comment">// 创建不含默认中间件的路由</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 全局中间件</span>
	<span class="token comment">// Logger 中间件会将日志写到 gin.DefaultWriter 即使指定 GIN_MODE=release</span>
	<span class="token comment">// 默认情况下 gin.DefaultWriter = os.Stdout</span>
	r<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Logger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    
	<span class="token comment">// Recovery 中间件从任何 panic 恢复 并且写入一个 500 状态码</span>
	r<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    
	<span class="token comment">// 可以随心添加中间件到任何你想要添加的路由上</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/benchmark&quot;</span><span class="token punctuation">,</span> <span class="token function">MyBenchLogger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> benchEndpoint<span class="token punctuation">)</span>

	<span class="token comment">// 认证分组</span>
	<span class="token comment">// authorized := r.Group(&quot;/&quot;, AuthRequired())</span>
	<span class="token comment">// exactly the same as:</span>
	authorized <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">)</span>
	<span class="token comment">// per group middleware! in this case we use the custom created</span>
	<span class="token comment">// AuthRequired() middleware just in the &quot;authorized&quot; group.</span>
	authorized<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span><span class="token function">AuthRequired</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		authorized<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/login&quot;</span><span class="token punctuation">,</span> loginEndpoint<span class="token punctuation">)</span>
		authorized<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/submit&quot;</span><span class="token punctuation">,</span> submitEndpoint<span class="token punctuation">)</span>
		authorized<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/read&quot;</span><span class="token punctuation">,</span> readEndpoint<span class="token punctuation">)</span>

		<span class="token comment">// 嵌套分组</span>
		testing <span class="token operator">:=</span> authorized<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">&quot;testing&quot;</span><span class="token punctuation">)</span>
		testing<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/analytics&quot;</span><span class="token punctuation">,</span> analyticsEndpoint<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="如何写日志" tabindex="-1"><a class="header-anchor" href="#如何写日志" aria-hidden="true">#</a> 如何写日志</h3><h3 id="how-to-write-log-file" tabindex="-1"><a class="header-anchor" href="#how-to-write-log-file" aria-hidden="true">#</a> How to write log file</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 当你不需要写入日志时颜色提示时, 关闭控制台颜色.</span>
    gin<span class="token punctuation">.</span><span class="token function">DisableConsoleColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment">// 将日志写入指定文件</span>
    f<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> os<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span><span class="token string">&quot;gin.log&quot;</span><span class="token punctuation">)</span>
    gin<span class="token punctuation">.</span>DefaultWriter <span class="token operator">=</span> io<span class="token punctuation">.</span><span class="token function">MultiWriter</span><span class="token punctuation">(</span>f<span class="token punctuation">)</span>

    <span class="token comment">// 同时使用文件与控制台记录日志</span>
    <span class="token comment">// gin.DefaultWriter = io.MultiWriter(f, os.Stdout)</span>

    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="自定义-log-format" tabindex="-1"><a class="header-anchor" href="#自定义-log-format" aria-hidden="true">#</a> 自定义 log format</h3><h3 id="custom-log-format" tabindex="-1"><a class="header-anchor" href="#custom-log-format" aria-hidden="true">#</a> Custom log format</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// LoggerWithFormatter 中间件将 log 写入 gin.DefaultWriter</span>
	<span class="token comment">// 默认情况下 gin.DefaultWriter = os.Stdout</span>
	router<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">LoggerWithFormatter</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span>param gin<span class="token punctuation">.</span>LogFormatterParams<span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>

		<span class="token comment">// 自定义格式</span>
		<span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">&quot;%s - [%s] \&quot;%s %s %s %d %s \&quot;%s\&quot; %s\&quot;\n&quot;</span><span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>ClientIP<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>TimeStamp<span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>RFC1123<span class="token punctuation">)</span><span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Method<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Path<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>Proto<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>StatusCode<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Latency<span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>Request<span class="token punctuation">.</span><span class="token function">UserAgent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
				param<span class="token punctuation">.</span>ErrorMessage<span class="token punctuation">,</span>
		<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>输出：</p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>::1 - <span class="token punctuation">[</span>Fri, 07 Dec <span class="token number">2018</span> <span class="token number">17</span>:04:38 JST<span class="token punctuation">]</span> <span class="token string">&quot;GET /ping HTTP/1.1 200 122.767µs &quot;</span>Mozilla/5.0 <span class="token punctuation">(</span>Macintosh<span class="token punctuation">;</span> Intel Mac OS X 10_11_6<span class="token punctuation">)</span> AppleWebKit/537.36 <span class="token punctuation">(</span>KHTML, like Gecko<span class="token punctuation">)</span> Chrome/71.0.3578.80 Safari/537.36<span class="token string">&quot; &quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="controlling-log-output-coloring" tabindex="-1"><a class="header-anchor" href="#controlling-log-output-coloring" aria-hidden="true">#</a> Controlling Log output coloring</h3><p>默认情况下，控制台输出的日志颜色依赖于检测到的 TTY。</p><p>永远不为日志着色:</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 禁用日志颜色</span>
    gin<span class="token punctuation">.</span><span class="token function">DisableConsoleColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment">// 创建一个包含默认中间件的 gin 路由器:</span>
    <span class="token comment">// logger and recovery (crash-free) middleware</span>
    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>总是为日志着色:</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// 强制使用日志颜色</span>
    gin<span class="token punctuation">.</span><span class="token function">DisableConsoleColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token comment">// 创建一个包含默认中间件的 gin 路由器:</span>
    <span class="token comment">// logger and recovery (crash-free) middleware</span>
    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="模型绑定与验证" tabindex="-1"><a class="header-anchor" href="#模型绑定与验证" aria-hidden="true">#</a> 模型绑定与验证</h3><h3 id="model-binding-and-validation" tabindex="-1"><a class="header-anchor" href="#model-binding-and-validation" aria-hidden="true">#</a> Model binding and validation</h3><p>使用 model binding 绑定请求主体到类型，Gin 支持绑定 JSON, XML, 标准表单。(foo=bar&amp;boo=baz)</p><p>Gin 使用 <a href="https://github.com/go-playground/validator" target="_blank" rel="noopener noreferrer"><strong>go-playground/validator.v8</strong></a> 验证。 在 <a href="http://godoc.org/gopkg.in/go-playground/validator.v8#hdr-Baked_In_Validators_and_Tags" target="_blank" rel="noopener noreferrer">此处</a> 查看有关标签用法的完整文档。</p><p>注意你需要在所需要绑定的字段设置对应的绑定标签。例如，当从 JSON 绑定时，设置 <code>json:&quot;fieldname&quot;</code></p><p>Gin 提供两种方法集绑定</p><ul><li><strong>Type</strong> - Must bind <ul><li><strong>Methods</strong> - <code>Bind</code>, <code>BindJSON</code>, <code>BindXML</code>, <code>BindQuery</code></li><li><strong>Behavior</strong> - 这些方法底层使用 <code>MustBindWith</code> 。如果绑定失败，该请求会使用 <code>c.AbortWithError(400, err).SetType(ErrorTypeBind)</code> 中止舍弃。 返回 400 状态码，设置 <code>Content-Type</code> 首部为 <code>text/plain; charset=utf-8</code>。注意如果你在此后想设置状态状态码，会导致一个 警告 <code>[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422</code>。 如果你想更好地掌控该行为，考虑使用 <code>ShouldBind</code> 方法。</li></ul></li><li><strong>Type</strong> - Should bind <ul><li><strong>Methods</strong> - <code>ShouldBind</code>, <code>ShouldBindJSON</code>, <code>ShouldBindXML</code>, <code>ShouldBindQuery</code></li><li><strong>Behavior</strong> - 这些方法底层使用 <code>ShouldBindWith</code>。如果绑定失败，由开发者掌控处理请求与错误。</li></ul></li></ul><p>Gin 会从首部 <code>Content-Type</code>字段推断绑定内容的类型，如果你确定需要绑定内容的类型，可以使用 <code>MustBindWith</code> 或者 <code>ShouldBindWith</code>。</p><p>你同样可以指定绑定必须提供的字段。如果一个带有 <code>binding:&quot;required&quot;</code> 标签的类型绑定时无对应值，将返回一个错误。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token comment">// Binding from JSON</span>
<span class="token keyword">type</span> Login <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	User     <span class="token builtin">string</span> <span class="token string">`form:&quot;user&quot; json:&quot;user&quot; xml:&quot;user&quot;  binding:&quot;required&quot;`</span>
	Password <span class="token builtin">string</span> <span class="token string">`form:&quot;password&quot; json:&quot;password&quot; xml:&quot;password&quot; binding:&quot;required&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Example for binding JSON ({&quot;user&quot;: &quot;manu&quot;, &quot;password&quot;: &quot;123&quot;})</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/loginJSON&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">var</span> json Login
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindJSON</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>json<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;error&quot;</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>
		
		<span class="token keyword">if</span> json<span class="token punctuation">.</span>User <span class="token operator">!=</span> <span class="token string">&quot;manu&quot;</span> <span class="token operator">||</span> json<span class="token punctuation">.</span>Password <span class="token operator">!=</span> <span class="token string">&quot;123&quot;</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnauthorized<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;unauthorized&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span> 
		
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;you are logged in&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Example for binding XML (</span>
	<span class="token comment">//	&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
	<span class="token comment">//	&lt;root&gt;</span>
	<span class="token comment">//		&lt;user&gt;user&lt;/user&gt;</span>
	<span class="token comment">//		&lt;password&gt;123&lt;/user&gt;</span>
	<span class="token comment">//	&lt;/root&gt;)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/loginXML&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">var</span> xml Login
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindXML</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>xml<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;error&quot;</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>
		
		<span class="token keyword">if</span> xml<span class="token punctuation">.</span>User <span class="token operator">!=</span> <span class="token string">&quot;manu&quot;</span> <span class="token operator">||</span> xml<span class="token punctuation">.</span>Password <span class="token operator">!=</span> <span class="token string">&quot;123&quot;</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnauthorized<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;unauthorized&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span> 
		
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;you are logged in&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Example for binding a HTML form (user=manu&amp;password=123)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/loginForm&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">var</span> form Login
		<span class="token comment">// This will infer what binder to use depending on the content-type header.</span>
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>form<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;error&quot;</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>
		
		<span class="token keyword">if</span> form<span class="token punctuation">.</span>User <span class="token operator">!=</span> <span class="token string">&quot;manu&quot;</span> <span class="token operator">||</span> form<span class="token punctuation">.</span>Password <span class="token operator">!=</span> <span class="token string">&quot;123&quot;</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusUnauthorized<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;unauthorized&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span> 
		
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;you are logged in&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>Sample request</strong></p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">curl</span> -v -X POST <span class="token punctuation">\</span>
  http://localhost:8080/loginJSON <span class="token punctuation">\</span>
  -H <span class="token string">&#39;content-type: application/json&#39;</span> <span class="token punctuation">\</span>
  -d <span class="token string">&#39;{ &quot;user&quot;: &quot;manu&quot; }&#39;</span>
<span class="token operator">&gt;</span> POST /loginJSON HTTP/1.1
<span class="token operator">&gt;</span> Host: localhost:8080
<span class="token operator">&gt;</span> User-Agent: curl/7.51.0
<span class="token operator">&gt;</span> Accept: */*
<span class="token operator">&gt;</span> content-type: application/json
<span class="token operator">&gt;</span> Content-Length: <span class="token number">18</span>
<span class="token operator">&gt;</span>
* upload completely sent off: <span class="token number">18</span> out of <span class="token number">18</span> bytes
<span class="token operator">&lt;</span> HTTP/1.1 <span class="token number">400</span> Bad Request
<span class="token operator">&lt;</span> Content-Type: application/json<span class="token punctuation">;</span> <span class="token assign-left variable">charset</span><span class="token operator">=</span>utf-8
<span class="token operator">&lt;</span> Date: Fri, 04 Aug <span class="token number">2017</span> 03:51:31 GMT
<span class="token operator">&lt;</span> Content-Length: <span class="token number">100</span>
<span class="token operator">&lt;</span>
<span class="token punctuation">{</span><span class="token string">&quot;error&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;Key: &#39;Login.Password&#39; Error:Field validation for &#39;Password&#39; failed on the &#39;required&#39; tag&quot;</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>跳过验证</strong></p><p>使用上面的 <code>curl</code> 命令，将返回错误。因为 <code>Password</code> 字段使用了 <code>binding:&quot;required&quot;</code>。 如果使用 <code>binding:&quot;-&quot;</code>，则不会返回错误。</p><h3 id="自定义验证器" tabindex="-1"><a class="header-anchor" href="#自定义验证器" aria-hidden="true">#</a> 自定义验证器</h3><h3 id="custom-validators" tabindex="-1"><a class="header-anchor" href="#custom-validators" aria-hidden="true">#</a> Custom Validators</h3><p>可以注册自定义验证器，查看 <a href="https://github.com/gin-gonic/examples/blob/master/custom-validation/server.go" target="_blank" rel="noopener noreferrer">example code</a>。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;net/http&quot;</span>
	<span class="token string">&quot;reflect&quot;</span>
	<span class="token string">&quot;time&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
	<span class="token string">&quot;github.com/gin-gonic/gin/binding&quot;</span>
	<span class="token string">&quot;gopkg.in/go-playground/validator.v8&quot;</span>
<span class="token punctuation">)</span>

<span class="token comment">// Booking contains binded and validated data.</span>
<span class="token keyword">type</span> Booking <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	CheckIn  time<span class="token punctuation">.</span>Time <span class="token string">`form:&quot;check_in&quot; binding:&quot;required,bookabledate&quot; time_format:&quot;2006-01-02&quot;`</span>
	CheckOut time<span class="token punctuation">.</span>Time <span class="token string">`form:&quot;check_out&quot; binding:&quot;required,gtfield=CheckIn&quot; time_format:&quot;2006-01-02&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">bookableDate</span><span class="token punctuation">(</span>
	v <span class="token operator">*</span>validator<span class="token punctuation">.</span>Validate<span class="token punctuation">,</span> topStruct reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span> currentStructOrField reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span>
	field reflect<span class="token punctuation">.</span>Value<span class="token punctuation">,</span> fieldType reflect<span class="token punctuation">.</span>Type<span class="token punctuation">,</span> fieldKind reflect<span class="token punctuation">.</span>Kind<span class="token punctuation">,</span> param <span class="token builtin">string</span><span class="token punctuation">,</span>
<span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span>
	<span class="token keyword">if</span> date<span class="token punctuation">,</span> ok <span class="token operator">:=</span> field<span class="token punctuation">.</span><span class="token function">Interface</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span>time<span class="token punctuation">.</span>Time<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
		today <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> today<span class="token punctuation">.</span><span class="token function">Year</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> date<span class="token punctuation">.</span><span class="token function">Year</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> today<span class="token punctuation">.</span><span class="token function">YearDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> date<span class="token punctuation">.</span><span class="token function">YearDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token boolean">false</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> <span class="token boolean">true</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token keyword">if</span> v<span class="token punctuation">,</span> ok <span class="token operator">:=</span> binding<span class="token punctuation">.</span>Validator<span class="token punctuation">.</span><span class="token function">Engine</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token operator">*</span>validator<span class="token punctuation">.</span>Validate<span class="token punctuation">)</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
		v<span class="token punctuation">.</span><span class="token function">RegisterValidation</span><span class="token punctuation">(</span><span class="token string">&quot;bookabledate&quot;</span><span class="token punctuation">,</span> bookableDate<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>

	route<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/bookable&quot;</span><span class="token punctuation">,</span> getBookable<span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8085&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">getBookable</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">var</span> b Booking
	<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>Query<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;Booking dates are valid!&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;error&quot;</span><span class="token punctuation">:</span> err<span class="token punctuation">.</span><span class="token function">Error</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">curl</span> <span class="token string">&quot;localhost:8085/bookable?check_in=2018-04-16&amp;check_out=2018-04-17&quot;</span>
<span class="token punctuation">{</span><span class="token string">&quot;message&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;Booking dates are valid!&quot;</span><span class="token punctuation">}</span>

$ <span class="token function">curl</span> <span class="token string">&quot;localhost:8085/bookable?check_in=2018-03-08&amp;check_out=2018-03-09&quot;</span>
<span class="token punctuation">{</span><span class="token string">&quot;error&quot;</span><span class="token builtin class-name">:</span><span class="token string">&quot;Key: &#39;Booking.CheckIn&#39; Error:Field validation for &#39;CheckIn&#39; failed on the &#39;bookabledate&#39; tag&quot;</span><span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><a href="https://github.com/go-playground/validator/releases/tag/v8.7" target="_blank" rel="noopener noreferrer">Struct level validations</a> 可以同样以此注册。 查看 <a href="https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations" target="_blank" rel="noopener noreferrer">struct-lvl-validation example</a> 学习更多。</p><h3 id="只绑定查询字符串" tabindex="-1"><a class="header-anchor" href="#只绑定查询字符串" aria-hidden="true">#</a> 只绑定查询字符串</h3><h3 id="only-bind-query-string" tabindex="-1"><a class="header-anchor" href="#only-bind-query-string" aria-hidden="true">#</a> Only Bind Query String</h3><p><code>ShouldBindQuery</code> 方法只从查询字符串绑定，而不包括 POST 方法提供的数据。 查看 <a href="https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017" target="_blank" rel="noopener noreferrer">detail information</a>。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;log&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">type</span> Person <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	Name    <span class="token builtin">string</span> <span class="token string">`form:&quot;name&quot;`</span>
	Address <span class="token builtin">string</span> <span class="token string">`form:&quot;address&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Any</span><span class="token punctuation">(</span><span class="token string">&quot;/testing&quot;</span><span class="token punctuation">,</span> startPage<span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8085&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">startPage</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">var</span> person Person
	<span class="token keyword">if</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindQuery</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>person<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;====== Only Bind By Query String ======&quot;</span><span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Name<span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Address<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;Success&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="绑定查询字符串或者-post-data" tabindex="-1"><a class="header-anchor" href="#绑定查询字符串或者-post-data" aria-hidden="true">#</a> 绑定查询字符串或者 Post Data</h3><h3 id="bind-query-string-or-post-data" tabindex="-1"><a class="header-anchor" href="#bind-query-string-or-post-data" aria-hidden="true">#</a> Bind Query String or Post Data</h3><p>查看 <a href="https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292" target="_blank" rel="noopener noreferrer">detail information</a>。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;log&quot;</span>
	<span class="token string">&quot;time&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">type</span> Person <span class="token keyword">struct</span> <span class="token punctuation">{</span>
        Name       <span class="token builtin">string</span>    <span class="token string">`form:&quot;name&quot;`</span>
        Address    <span class="token builtin">string</span>    <span class="token string">`form:&quot;address&quot;`</span>
        Birthday   time<span class="token punctuation">.</span>Time <span class="token string">`form:&quot;birthday&quot; time_format:&quot;2006-01-02&quot; time_utc:&quot;1&quot;`</span>
        CreateTime time<span class="token punctuation">.</span>Time <span class="token string">`form:&quot;createTime&quot; time_format:&quot;unixNano&quot;`</span>
        UnixTime   time<span class="token punctuation">.</span>Time <span class="token string">`form:&quot;unixTime&quot; time_format:&quot;unix&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/testing&quot;</span><span class="token punctuation">,</span> startPage<span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8085&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">startPage</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	<span class="token keyword">var</span> person Person
	<span class="token comment">// If `GET`, only `Form` binding engine (`query`) used.</span>
	<span class="token comment">// If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).</span>
	<span class="token comment">// See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48</span>
        <span class="token keyword">if</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>person<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
                log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Name<span class="token punctuation">)</span>
                log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Address<span class="token punctuation">)</span>
                log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>Birthday<span class="token punctuation">)</span>
                log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>CreateTime<span class="token punctuation">)</span>
                log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>UnixTime<span class="token punctuation">)</span>
        <span class="token punctuation">}</span>

	c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;Success&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>测试:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">curl</span> -X GET <span class="token string">&quot;localhost:8085/testing?name=appleboy&amp;address=xyz&amp;birthday=1992-03-15&amp;createTime=1562400033000000123&amp;unixTime=1562400033&quot;</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="绑定-uri" tabindex="-1"><a class="header-anchor" href="#绑定-uri" aria-hidden="true">#</a> 绑定 Uri</h3><h3 id="bind-uri" tabindex="-1"><a class="header-anchor" href="#bind-uri" aria-hidden="true">#</a> Bind Uri</h3><p>查看 <a href="https://github.com/gin-gonic/gin/issues/846" target="_blank" rel="noopener noreferrer">detail information</a>。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>

<span class="token keyword">type</span> Person <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	ID <span class="token builtin">string</span> <span class="token string">`uri:&quot;id&quot; binding:&quot;required,uuid&quot;`</span>
	Name <span class="token builtin">string</span> <span class="token string">`uri:&quot;name&quot; binding:&quot;required&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	route <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/:name/:id&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">var</span> person Person
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindUri</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>person<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">400</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;msg&quot;</span><span class="token punctuation">:</span> err<span class="token punctuation">}</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;name&quot;</span><span class="token punctuation">:</span> person<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token string">&quot;uuid&quot;</span><span class="token punctuation">:</span> person<span class="token punctuation">.</span>ID<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	route<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8088&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>测试:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">curl</span> -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
$ <span class="token function">curl</span> -v localhost:8088/thinkerou/not-uuid
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="绑定-header" tabindex="-1"><a class="header-anchor" href="#绑定-header" aria-hidden="true">#</a> 绑定 Header</h3><h3 id="bind-header" tabindex="-1"><a class="header-anchor" href="#bind-header" aria-hidden="true">#</a> Bind Header</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;fmt&quot;</span>
	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">type</span> testHeader <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	Rate   <span class="token builtin">int</span>    <span class="token string">`header:&quot;Rate&quot;`</span>
	Domain <span class="token builtin">string</span> <span class="token string">`header:&quot;Domain&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		h <span class="token operator">:=</span> testHeader<span class="token punctuation">{</span><span class="token punctuation">}</span>

		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindHeader</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>h<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
		<span class="token punctuation">}</span>

		fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;%#v\n&quot;</span><span class="token punctuation">,</span> h<span class="token punctuation">)</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;Rate&quot;</span><span class="token punctuation">:</span> h<span class="token punctuation">.</span>Rate<span class="token punctuation">,</span> <span class="token string">&quot;Domain&quot;</span><span class="token punctuation">:</span> h<span class="token punctuation">.</span>Domain<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment">// client</span>
<span class="token comment">// curl -H &quot;rate:300&quot; -H &quot;domain:music&quot; 127.0.0.1:8080/</span>
<span class="token comment">// output</span>
<span class="token comment">// {&quot;Domain&quot;:&quot;music&quot;,&quot;Rate&quot;:300}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="绑定-html-复选框" tabindex="-1"><a class="header-anchor" href="#绑定-html-复选框" aria-hidden="true">#</a> 绑定 HTML 复选框</h3><h3 id="bind-html-checkboxes" tabindex="-1"><a class="header-anchor" href="#bind-html-checkboxes" aria-hidden="true">#</a> Bind HTML checkboxes</h3><p>查看 <a href="https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092" target="_blank" rel="noopener noreferrer">detail information</a>。</p><p>main.go</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token operator">...</span>

<span class="token keyword">type</span> myForm <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    Colors <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span> <span class="token string">`form:&quot;colors[]&quot;`</span>
<span class="token punctuation">}</span>

<span class="token operator">...</span>

<span class="token keyword">func</span> <span class="token function">formHandler</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> fakeForm myForm
    c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>fakeForm<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;color&quot;</span><span class="token punctuation">:</span> fakeForm<span class="token punctuation">.</span>Colors<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token operator">...</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>form.html</p><div class="language-html ext-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>/<span class="token punctuation">&quot;</span></span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>POST<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Check some colors<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>red<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>Red<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>checkbox<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>colors[]<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>red<span class="token punctuation">&quot;</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>red<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>green<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>Green<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>checkbox<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>colors[]<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>green<span class="token punctuation">&quot;</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>green<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>blue<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>Blue<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>label</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>checkbox<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>colors[]<span class="token punctuation">&quot;</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>blue<span class="token punctuation">&quot;</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>blue<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>submit<span class="token punctuation">&quot;</span></span> <span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>form</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>结果:</p><div class="language-text ext-text line-numbers-mode"><pre class="language-text"><code>{&quot;color&quot;:[&quot;red&quot;,&quot;green&quot;,&quot;blue&quot;]}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="multipart-urlencoded-表单绑定" tabindex="-1"><a class="header-anchor" href="#multipart-urlencoded-表单绑定" aria-hidden="true">#</a> Multipart/Urlencoded 表单绑定</h3><h3 id="multipart-urlencoded-binding" tabindex="-1"><a class="header-anchor" href="#multipart-urlencoded-binding" aria-hidden="true">#</a> Multipart/Urlencoded binding</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">type</span> ProfileForm <span class="token keyword">struct</span> <span class="token punctuation">{</span>
	Name   <span class="token builtin">string</span>                <span class="token string">`form:&quot;name&quot; binding:&quot;required&quot;`</span>
	Avatar <span class="token operator">*</span>multipart<span class="token punctuation">.</span>FileHeader <span class="token string">`form:&quot;avatar&quot; binding:&quot;required&quot;`</span>

	<span class="token comment">// or for multiple files</span>
	<span class="token comment">// Avatars []*multipart.FileHeader `form:&quot;avatar&quot; binding:&quot;required&quot;`</span>
<span class="token punctuation">}</span>


<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/profile&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 你可以绑定 multipart form 通过明确的绑定声明：</span>
		<span class="token comment">// c.ShouldBindWith(&amp;form, binding.Form)</span>
		<span class="token comment">// 或者简单地使用 ShouldBind method 自动绑定：</span>
		<span class="token keyword">var</span> form ProfileForm
		<span class="token comment">// 该情况下 gin 会自动选择合适的绑定类型</span>
		<span class="token keyword">if</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>form<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusBadRequest<span class="token punctuation">,</span> <span class="token string">&quot;bad request&quot;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>

		err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">SaveUploadedFile</span><span class="token punctuation">(</span>form<span class="token punctuation">.</span>Avatar<span class="token punctuation">,</span> form<span class="token punctuation">.</span>Avatar<span class="token punctuation">.</span>Filename<span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusInternalServerError<span class="token punctuation">,</span> <span class="token string">&quot;unknown error&quot;</span><span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>

        <span class="token comment">// db.Save(&amp;form)</span>

        c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;ok&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>测试:</p><div class="language-bash ext-sh line-numbers-mode"><pre class="language-bash"><code>$ <span class="token function">curl</span> -X POST -v --form <span class="token assign-left variable">name</span><span class="token operator">=</span>user --form <span class="token string">&quot;avatar=@./avatar.png&quot;</span> http://localhost:8080/profile
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="xml-json-yaml-and-protobuf-渲染" tabindex="-1"><a class="header-anchor" href="#xml-json-yaml-and-protobuf-渲染" aria-hidden="true">#</a> XML, JSON, YAML and ProtoBuf 渲染</h3><h3 id="xml-json-yaml-and-protobuf-rendering" tabindex="-1"><a class="header-anchor" href="#xml-json-yaml-and-protobuf-rendering" aria-hidden="true">#</a> XML, JSON, YAML and ProtoBuf rendering</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// gin.H 是 map[string]interface{} 的快捷方法</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someJSON&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;hey&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/moreJSON&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 你同样可以使用结构体</span>
		<span class="token keyword">var</span> msg <span class="token keyword">struct</span> <span class="token punctuation">{</span>
			Name    <span class="token builtin">string</span> <span class="token string">`json:&quot;user&quot;`</span>
			Message <span class="token builtin">string</span>
			Number  <span class="token builtin">int</span>
		<span class="token punctuation">}</span>
		msg<span class="token punctuation">.</span>Name <span class="token operator">=</span> <span class="token string">&quot;Lena&quot;</span>
		msg<span class="token punctuation">.</span>Message <span class="token operator">=</span> <span class="token string">&quot;hey&quot;</span>
		msg<span class="token punctuation">.</span>Number <span class="token operator">=</span> <span class="token number">123</span>
		<span class="token comment">// 注意 msg.Name 在 JSON 中变成了用 &quot;user&quot; 表示</span>
		<span class="token comment">// 输出： {&quot;user&quot;: &quot;Lena&quot;, &quot;Message&quot;: &quot;hey&quot;, &quot;Number&quot;: 123}</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> msg<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someXML&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">XML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;hey&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someYAML&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">YAML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;message&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;hey&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someProtoBuf&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		reps <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">int64</span><span class="token punctuation">{</span><span class="token function">int64</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">int64</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">}</span>
		label <span class="token operator">:=</span> <span class="token string">&quot;test&quot;</span>
		<span class="token comment">// 该 protobuf 的定义在 testdata/protoexample 文件中</span>
		data <span class="token operator">:=</span> <span class="token operator">&amp;</span>protoexample<span class="token punctuation">.</span>Test<span class="token punctuation">{</span>
			Label<span class="token punctuation">:</span> <span class="token operator">&amp;</span>label<span class="token punctuation">,</span>
			Reps<span class="token punctuation">:</span>  reps<span class="token punctuation">,</span>
		<span class="token punctuation">}</span>
		<span class="token comment">// 数据在响应中变成二进制格式</span>
		<span class="token comment">// 输出protoexample.Test protobuf序列化数据</span>
		c<span class="token punctuation">.</span><span class="token function">ProtoBuf</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="securejson" tabindex="-1"><a class="header-anchor" href="#securejson" aria-hidden="true">#</a> SecureJSON</h4><p>使用 SecureJSON 防止 JSON 劫持. Default prepends <code>&quot;while(1),&quot;</code> to response body if the given struct is array values.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    
	<span class="token comment">// 可以使用自定义的安全 json 前缀</span>
	<span class="token comment">// r.SecureJsonPrefix(&quot;)]}&#39;,\n&quot;)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someJSON&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		names <span class="token operator">:=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">&quot;lena&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;austin&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;foo&quot;</span><span class="token punctuation">}</span>

		<span class="token comment">// 输出：   while(1);[&quot;lena&quot;,&quot;austin&quot;,&quot;foo&quot;]</span>
		c<span class="token punctuation">.</span><span class="token function">SecureJSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> names<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="jsonp" tabindex="-1"><a class="header-anchor" href="#jsonp" aria-hidden="true">#</a> JSONP</h4><h4 id="jsonp-1" tabindex="-1"><a class="header-anchor" href="#jsonp-1" aria-hidden="true">#</a> JSONP</h4><p>使用 JSONP 请求来自不同域名中的服务器的数据。如果存在查询参数回调，则将回调添加到响应体</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/JSONP&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		data <span class="token operator">:=</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;foo&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;bar&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//callback is x</span>
		<span class="token comment">// Will output  :   x({\&quot;foo\&quot;:\&quot;bar\&quot;})</span>
		c<span class="token punctuation">.</span><span class="token function">JSONP</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>

        <span class="token comment">// client</span>
        <span class="token comment">// curl http://127.0.0.1:8080/JSONP?callback=x</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="asciijson" tabindex="-1"><a class="header-anchor" href="#asciijson" aria-hidden="true">#</a> AsciiJSON</h4><p>使用 AsciiJSON 生成只由 ASCII 编码的 JSON 字符。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someJSON&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		data <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span>
			<span class="token string">&quot;lang&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;GO语言&quot;</span><span class="token punctuation">,</span>
			<span class="token string">&quot;tag&quot;</span><span class="token punctuation">:</span>  <span class="token string">&quot;&lt;br&gt;&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span>

		<span class="token comment">// will output : {&quot;lang&quot;:&quot;GO\u8bed\u8a00&quot;,&quot;tag&quot;:&quot;\u003cbr\u003e&quot;}</span>
		c<span class="token punctuation">.</span><span class="token function">AsciiJSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> data<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="purejson" tabindex="-1"><a class="header-anchor" href="#purejson" aria-hidden="true">#</a> PureJSON</h4><p>Normally, JSON replaces special HTML characters with their unicode entities, e.g. <code>&lt;</code> becomes <code>\u003c</code>. If you want to encode such characters literally, you can use PureJSON instead. This feature is unavailable in Go 1.6 and lower.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	
	<span class="token comment">// Serves unicode entities</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/json&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;html&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;&lt;b&gt;Hello, world!&lt;/b&gt;&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	
	<span class="token comment">// Serves literal characters</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/purejson&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">PureJSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;html&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;&lt;b&gt;Hello, world!&lt;/b&gt;&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	
	<span class="token comment">// listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>&quot;<span class="token punctuation">:</span><span class="token number">8080</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="提供静态文件" tabindex="-1"><a class="header-anchor" href="#提供静态文件" aria-hidden="true">#</a> 提供静态文件</h3><h3 id="serving-static-files" tabindex="-1"><a class="header-anchor" href="#serving-static-files" aria-hidden="true">#</a> Serving static files</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Static</span><span class="token punctuation">(</span><span class="token string">&quot;/assets&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;./assets&quot;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">StaticFS</span><span class="token punctuation">(</span><span class="token string">&quot;/more_static&quot;</span><span class="token punctuation">,</span> http<span class="token punctuation">.</span><span class="token function">Dir</span><span class="token punctuation">(</span><span class="token string">&quot;my_file_system&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">StaticFile</span><span class="token punctuation">(</span><span class="token string">&quot;/favicon.ico&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;./resources/favicon.ico&quot;</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="serving-data-from-reader" tabindex="-1"><a class="header-anchor" href="#serving-data-from-reader" aria-hidden="true">#</a> Serving data from reader</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/someDataFromReader&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		response<span class="token punctuation">,</span> err <span class="token operator">:=</span> http<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">&quot;https://raw.githubusercontent.com/gin-gonic/logo/master/color.png&quot;</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">||</span> response<span class="token punctuation">.</span>StatusCode <span class="token operator">!=</span> http<span class="token punctuation">.</span>StatusOK <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">Status</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusServiceUnavailable<span class="token punctuation">)</span>
			<span class="token keyword">return</span>
		<span class="token punctuation">}</span>

		reader <span class="token operator">:=</span> response<span class="token punctuation">.</span>Body
		contentLength <span class="token operator">:=</span> response<span class="token punctuation">.</span>ContentLength
		contentType <span class="token operator">:=</span> response<span class="token punctuation">.</span>Header<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">&quot;Content-Type&quot;</span><span class="token punctuation">)</span>

		extraHeaders <span class="token operator">:=</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span>
			<span class="token string">&quot;Content-Disposition&quot;</span><span class="token punctuation">:</span> <span class="token string">`attachment; filename=&quot;gopher.png&quot;`</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span>

		c<span class="token punctuation">.</span><span class="token function">DataFromReader</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> contentLength<span class="token punctuation">,</span> contentType<span class="token punctuation">,</span> reader<span class="token punctuation">,</span> extraHeaders<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="html-渲染" tabindex="-1"><a class="header-anchor" href="#html-渲染" aria-hidden="true">#</a> HTML 渲染</h3><h3 id="html-rendering" tabindex="-1"><a class="header-anchor" href="#html-rendering" aria-hidden="true">#</a> HTML rendering</h3><p>使用 <code>LoadHTMLGlob()</code> 或者 <code>LoadHTMLFiles()</code></p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	
	<span class="token comment">// 加载所有的模板文件</span>
	router<span class="token punctuation">.</span><span class="token function">LoadHTMLGlob</span><span class="token punctuation">(</span><span class="token string">&quot;templates/*&quot;</span><span class="token punctuation">)</span>

	<span class="token comment">// 加载某个模板文件</span>
	<span class="token comment">// router.LoadHTMLFiles(&quot;templates/template1.html&quot;, &quot;templates/template2.html&quot;)</span>
	
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/index&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;index.tmpl&quot;</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;title&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;Main website&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>templates/index.tmpl</code></p><div class="language-html ext-html line-numbers-mode"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">&gt;</span></span>
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span>
		{{ .title }}
	<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="渲染原生-html" tabindex="-1"><a class="header-anchor" href="#渲染原生-html" aria-hidden="true">#</a> 渲染原生 HTML</h4><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code>g<span class="token punctuation">.</span><span class="token function">LoagHTMLFiles</span><span class="token punctuation">(</span>filepath<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span>staticPath<span class="token punctuation">,</span> <span class="token string">&quot;index.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;index.html&quot;</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

<span class="token comment">// 或者</span>
router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   c<span class="token punctuation">.</span><span class="token function">File</span><span class="token punctuation">(</span>filepath<span class="token punctuation">.</span><span class="token function">Join</span><span class="token punctuation">(</span>staticPath<span class="token punctuation">,</span> <span class="token string">&quot;index.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="使用不同文件夹相同名称的-html-模板" tabindex="-1"><a class="header-anchor" href="#使用不同文件夹相同名称的-html-模板" aria-hidden="true">#</a> 使用不同文件夹相同名称的 HTML 模板</h4><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">LoadHTMLGlob</span><span class="token punctuation">(</span><span class="token string">&quot;templates/**/*&quot;</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/posts/index&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;posts/index.tmpl&quot;</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;title&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;Posts&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/users/index&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;users/index.tmpl&quot;</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;title&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;Users&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>templates/posts/index.tmpl</code></p><div class="language-html ext-html line-numbers-mode"><pre class="language-html"><code>{{ define &quot;posts/index.tmpl&quot; }}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span>
	{{ .title }}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Using posts/index.tmpl<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
{{ end }}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>templates/users/index.tmpl</code></p><div class="language-html ext-html line-numbers-mode"><pre class="language-html"><code>{{ define &quot;users/index.tmpl&quot; }}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">&gt;</span></span>
	{{ .title }}
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>Using users/index.tmpl<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">&gt;</span></span>
{{ end }}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="自定义模板渲染器" tabindex="-1"><a class="header-anchor" href="#自定义模板渲染器" aria-hidden="true">#</a> 自定义模板渲染器</h4><p>可以使用自定义 HTML 模板渲染器</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token string">&quot;html/template&quot;</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	html <span class="token operator">:=</span> template<span class="token punctuation">.</span><span class="token function">Must</span><span class="token punctuation">(</span>template<span class="token punctuation">.</span><span class="token function">ParseFiles</span><span class="token punctuation">(</span><span class="token string">&quot;file1&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;file2&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">SetHTMLTemplate</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="自定义分隔符" tabindex="-1"><a class="header-anchor" href="#自定义分隔符" aria-hidden="true">#</a> 自定义分隔符</h4><p>可以自定义分隔符</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code>	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Delims</span><span class="token punctuation">(</span><span class="token string">&quot;{[{&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;}]}&quot;</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">LoadHTMLGlob</span><span class="token punctuation">(</span><span class="token string">&quot;/path/to/templates&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="自定义模板函数" tabindex="-1"><a class="header-anchor" href="#自定义模板函数" aria-hidden="true">#</a> 自定义模板函数</h4><p>查看细节 <a href="https://github.com/gin-gonic/examples/tree/master/template" target="_blank" rel="noopener noreferrer">example code</a>.</p><p><code>main.go</code></p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">&quot;fmt&quot;</span>
    <span class="token string">&quot;html/template&quot;</span>
    <span class="token string">&quot;net/http&quot;</span>
    <span class="token string">&quot;time&quot;</span>

    <span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">formatAsDate</span><span class="token punctuation">(</span>t time<span class="token punctuation">.</span>Time<span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span>
    year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> day <span class="token operator">:=</span> t<span class="token punctuation">.</span><span class="token function">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token keyword">return</span> fmt<span class="token punctuation">.</span><span class="token function">Sprintf</span><span class="token punctuation">(</span><span class="token string">&quot;%d%02d/%02d&quot;</span><span class="token punctuation">,</span> year<span class="token punctuation">,</span> month<span class="token punctuation">,</span> day<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">Delims</span><span class="token punctuation">(</span><span class="token string">&quot;{[{&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;}]}&quot;</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">SetFuncMap</span><span class="token punctuation">(</span>template<span class="token punctuation">.</span>FuncMap<span class="token punctuation">{</span>
        <span class="token string">&quot;formatAsDate&quot;</span><span class="token punctuation">:</span> formatAsDate<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
    router<span class="token punctuation">.</span><span class="token function">LoadHTMLFiles</span><span class="token punctuation">(</span><span class="token string">&quot;./testdata/template/raw.tmpl&quot;</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/raw&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;raw.tmpl&quot;</span><span class="token punctuation">,</span> <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token builtin">string</span><span class="token punctuation">]</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">{</span>
            <span class="token string">&quot;now&quot;</span><span class="token punctuation">:</span> time<span class="token punctuation">.</span><span class="token function">Date</span><span class="token punctuation">(</span><span class="token number">2017</span><span class="token punctuation">,</span> <span class="token number">07</span><span class="token punctuation">,</span> <span class="token number">01</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> time<span class="token punctuation">.</span>UTC<span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><code>raw.tmpl</code></p><div class="language-html ext-html line-numbers-mode"><pre class="language-html"><code>Date: {[{.now | formatAsDate}]}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><p>显示：</p><div class="language-text ext-text line-numbers-mode"><pre class="language-text"><code>Date: 2017/07/01
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div></div></div><h3 id="多模板" tabindex="-1"><a class="header-anchor" href="#多模板" aria-hidden="true">#</a> 多模板</h3><h3 id="multitemplate" tabindex="-1"><a class="header-anchor" href="#multitemplate" aria-hidden="true">#</a> Multitemplate</h3><p>Gin 默认情况下只允许使用一个模板文件. 点击 <a href="https://github.com/gin-contrib/multitemplate" target="_blank" rel="noopener noreferrer">这里</a> 看如何使用如 go 1.6 <code>block template</code> 来实现多模板渲染.</p><h3 id="重定向" tabindex="-1"><a class="header-anchor" href="#重定向" aria-hidden="true">#</a> 重定向</h3><h3 id="redirects" tabindex="-1"><a class="header-anchor" href="#redirects" aria-hidden="true">#</a> Redirects</h3><p>发起一个 HTTP 重定向很容易，支持内部与外部链接。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code>r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/test&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	c<span class="token punctuation">.</span><span class="token function">Redirect</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusMovedPermanently<span class="token punctuation">,</span> <span class="token string">&quot;http://www.google.com/&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>发起一个路由重定向，使用 <code>HandleContext</code>。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code>r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/test&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path <span class="token operator">=</span> <span class="token string">&quot;/test2&quot;</span>
    r<span class="token punctuation">.</span><span class="token function">HandleContext</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/test2&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;hello&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;world&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="自定义中间件" tabindex="-1"><a class="header-anchor" href="#自定义中间件" aria-hidden="true">#</a> 自定义中间件</h3><h3 id="custom-middleware" tabindex="-1"><a class="header-anchor" href="#custom-middleware" aria-hidden="true">#</a> Custom Middleware</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">Logger</span><span class="token punctuation">(</span><span class="token punctuation">)</span> gin<span class="token punctuation">.</span>HandlerFunc <span class="token punctuation">{</span>
	<span class="token keyword">return</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		t <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Now</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

		<span class="token comment">// 设置变量example</span>
		c<span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span><span class="token string">&quot;example&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;12345&quot;</span><span class="token punctuation">)</span>

		<span class="token comment">// 请求之前</span>

		c<span class="token punctuation">.</span><span class="token function">Next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

		<span class="token comment">// 请求之后</span>
		latency <span class="token operator">:=</span> time<span class="token punctuation">.</span><span class="token function">Since</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Print</span><span class="token punctuation">(</span>latency<span class="token punctuation">)</span>

		<span class="token comment">// 访问我们发送的状态</span>
		status <span class="token operator">:=</span> c<span class="token punctuation">.</span>Writer<span class="token punctuation">.</span><span class="token function">Status</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>status<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span><span class="token function">Logger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/test&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		example <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">MustGet</span><span class="token punctuation">(</span><span class="token string">&quot;example&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span>

		<span class="token comment">// it would print: &quot;12345&quot;</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>example<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="使用-basicauth-中间件" tabindex="-1"><a class="header-anchor" href="#使用-basicauth-中间件" aria-hidden="true">#</a> 使用 BasicAuth() 中间件</h3><h3 id="using-basicauth-middleware" tabindex="-1"><a class="header-anchor" href="#using-basicauth-middleware" aria-hidden="true">#</a> Using BasicAuth middleware</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token comment">// 模拟隐私数据</span>
<span class="token keyword">var</span> secrets <span class="token operator">=</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
	<span class="token string">&quot;foo&quot;</span><span class="token punctuation">:</span>    gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;email&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;foo@bar.com&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;phone&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;123433&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
	<span class="token string">&quot;austin&quot;</span><span class="token punctuation">:</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;email&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;austin@example.com&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;phone&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;666&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
	<span class="token string">&quot;lena&quot;</span><span class="token punctuation">:</span>   gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;email&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;lena@guapa.com&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;phone&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;523443&quot;</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// 下面分组使用 gin.BasicAuth() 中间件</span>
	<span class="token comment">// gin.Accounts是map[string]string的快捷方法</span>
	authorized <span class="token operator">:=</span> r<span class="token punctuation">.</span><span class="token function">Group</span><span class="token punctuation">(</span><span class="token string">&quot;/admin&quot;</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span><span class="token function">BasicAuth</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span>Accounts<span class="token punctuation">{</span>
		<span class="token string">&quot;foo&quot;</span><span class="token punctuation">:</span>    <span class="token string">&quot;bar&quot;</span><span class="token punctuation">,</span>
		<span class="token string">&quot;austin&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;1234&quot;</span><span class="token punctuation">,</span>
		<span class="token string">&quot;lena&quot;</span><span class="token punctuation">:</span>   <span class="token string">&quot;hello2&quot;</span><span class="token punctuation">,</span>
		<span class="token string">&quot;manu&quot;</span><span class="token punctuation">:</span>   <span class="token string">&quot;4321&quot;</span><span class="token punctuation">,</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

	<span class="token comment">// /admin/secrets 端点</span>
	<span class="token comment">// 点击访问 &quot;localhost:8080/admin/secrets</span>
	authorized<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/secrets&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 获取用户,由BasicAuth middleware代理设置</span>
		user <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">MustGet</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span>AuthUserKey<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token punctuation">(</span><span class="token builtin">string</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> secret<span class="token punctuation">,</span> ok <span class="token operator">:=</span> secrets<span class="token punctuation">[</span>user<span class="token punctuation">]</span><span class="token punctuation">;</span> ok <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;user&quot;</span><span class="token punctuation">:</span> user<span class="token punctuation">,</span> <span class="token string">&quot;secret&quot;</span><span class="token punctuation">:</span> secret<span class="token punctuation">}</span><span class="token punctuation">)</span>
		<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
			c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span><span class="token string">&quot;user&quot;</span><span class="token punctuation">:</span> user<span class="token punctuation">,</span> <span class="token string">&quot;secret&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;NO SECRET :(&quot;</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="中间件中的协程" tabindex="-1"><a class="header-anchor" href="#中间件中的协程" aria-hidden="true">#</a> 中间件中的协程</h3><h3 id="goroutines-inside-a-middleware" tabindex="-1"><a class="header-anchor" href="#goroutines-inside-a-middleware" aria-hidden="true">#</a> Goroutines inside a middleware</h3><p>在中间件或者处理器中开启协程时，<strong>不应</strong>使用原来的 context 上下文，只可以使用一个只读的副本。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/long_async&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 创建副本用于协程之中</span>
		cCp <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token comment">// 假设一个运行5秒的任务</span>
			time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>

			<span class="token comment">// 注意你在使用context的副本</span>
			log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Done! in path &quot;</span> <span class="token operator">+</span> cCp<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path<span class="token punctuation">)</span>
		<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/long_sync&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// 假设一个运行5秒的任务</span>
		time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>

		<span class="token comment">// 不在协程中，可直接使用context</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Done! in path &quot;</span> <span class="token operator">+</span> c<span class="token punctuation">.</span>Request<span class="token punctuation">.</span>URL<span class="token punctuation">.</span>Path<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and serve on 0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="自定义-http-配置" tabindex="-1"><a class="header-anchor" href="#自定义-http-配置" aria-hidden="true">#</a> 自定义 HTTP 配置</h3><h3 id="custom-http-configuration" tabindex="-1"><a class="header-anchor" href="#custom-http-configuration" aria-hidden="true">#</a> Custom HTTP configuration</h3><p>直接使用 <code>http.ListenAndServe()</code> 如下：</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	http<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">,</span> router<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>或者</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	s <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">{</span>
		Addr<span class="token punctuation">:</span>           <span class="token string">&quot;:8080&quot;</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span>        router<span class="token punctuation">,</span>
		ReadTimeout<span class="token punctuation">:</span>    <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		WriteTimeout<span class="token punctuation">:</span>   <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		MaxHeaderBytes<span class="token punctuation">:</span> <span class="token number">1</span> <span class="token operator">&lt;&lt;</span> <span class="token number">20</span><span class="token punctuation">,</span>
	<span class="token punctuation">}</span>
	s<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="support-let-s-encrypt" tabindex="-1"><a class="header-anchor" href="#support-let-s-encrypt" aria-hidden="true">#</a> Support Let&#39;s Encrypt</h3><p>example for 1-line LetsEncrypt HTTPS servers.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;log&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/autotls&quot;</span>
	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Ping handler</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>autotls<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> <span class="token string">&quot;example1.com&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;example2.com&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>自定义 autocert 管理器的示例.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;log&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/autotls&quot;</span>
	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
	<span class="token string">&quot;golang.org/x/crypto/acme/autocert&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Ping handler</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	m <span class="token operator">:=</span> autocert<span class="token punctuation">.</span>Manager<span class="token punctuation">{</span>
		Prompt<span class="token punctuation">:</span>     autocert<span class="token punctuation">.</span>AcceptTOS<span class="token punctuation">,</span>
		HostPolicy<span class="token punctuation">:</span> autocert<span class="token punctuation">.</span><span class="token function">HostWhitelist</span><span class="token punctuation">(</span><span class="token string">&quot;example1.com&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;example2.com&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		Cache<span class="token punctuation">:</span>      autocert<span class="token punctuation">.</span><span class="token function">DirCache</span><span class="token punctuation">(</span><span class="token string">&quot;/var/www/.cache&quot;</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
	<span class="token punctuation">}</span>

	log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>autotls<span class="token punctuation">.</span><span class="token function">RunWithManager</span><span class="token punctuation">(</span>r<span class="token punctuation">,</span> <span class="token operator">&amp;</span>m<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="使用-gin-运行多服务" tabindex="-1"><a class="header-anchor" href="#使用-gin-运行多服务" aria-hidden="true">#</a> 使用 Gin 运行多服务</h3><h3 id="run-multiple-service-using-gin" tabindex="-1"><a class="header-anchor" href="#run-multiple-service-using-gin" aria-hidden="true">#</a> Run multiple service using Gin</h3><p>请参阅 <a href="https://github.com/gin-gonic/gin/issues/346" target="_blank" rel="noopener noreferrer">问题</a> 并尝试以下示例：</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;log&quot;</span>
	<span class="token string">&quot;net/http&quot;</span>
	<span class="token string">&quot;time&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
	<span class="token string">&quot;golang.org/x/sync/errgroup&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">var</span> <span class="token punctuation">(</span>
	g errgroup<span class="token punctuation">.</span>Group
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">router01</span><span class="token punctuation">(</span><span class="token punctuation">)</span> http<span class="token punctuation">.</span>Handler <span class="token punctuation">{</span>
	e <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>
			http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
			gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
				<span class="token string">&quot;code&quot;</span><span class="token punctuation">:</span>  http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
				<span class="token string">&quot;error&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;Welcome server 01&quot;</span><span class="token punctuation">,</span>
			<span class="token punctuation">}</span><span class="token punctuation">,</span>
		<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token keyword">return</span> e
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">router02</span><span class="token punctuation">(</span><span class="token punctuation">)</span> http<span class="token punctuation">.</span>Handler <span class="token punctuation">{</span>
	e <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">Use</span><span class="token punctuation">(</span>gin<span class="token punctuation">.</span><span class="token function">Recovery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
	e<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>
			http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
			gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
				<span class="token string">&quot;code&quot;</span><span class="token punctuation">:</span>  http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span>
				<span class="token string">&quot;error&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;Welcome server 02&quot;</span><span class="token punctuation">,</span>
			<span class="token punctuation">}</span><span class="token punctuation">,</span>
		<span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token keyword">return</span> e
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	server01 <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">{</span>
		Addr<span class="token punctuation">:</span>         <span class="token string">&quot;:8080&quot;</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span>      <span class="token function">router01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		ReadTimeout<span class="token punctuation">:</span>  <span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		WriteTimeout<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
	<span class="token punctuation">}</span>

	server02 <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">{</span>
		Addr<span class="token punctuation">:</span>         <span class="token string">&quot;:8081&quot;</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span>      <span class="token function">router02</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
		ReadTimeout<span class="token punctuation">:</span>  <span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
		WriteTimeout<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">,</span>
	<span class="token punctuation">}</span>

	g<span class="token punctuation">.</span><span class="token function">Go</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
		<span class="token keyword">return</span> server01<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	g<span class="token punctuation">.</span><span class="token function">Go</span><span class="token punctuation">(</span><span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span>
		<span class="token keyword">return</span> server02<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token keyword">if</span> err <span class="token operator">:=</span> g<span class="token punctuation">.</span><span class="token function">Wait</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
		log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="优雅重启或停止" tabindex="-1"><a class="header-anchor" href="#优雅重启或停止" aria-hidden="true">#</a> 优雅重启或停止</h3><h3 id="graceful-restart-or-stop" tabindex="-1"><a class="header-anchor" href="#graceful-restart-or-stop" aria-hidden="true">#</a> Graceful restart or stop</h3><p>以下方式可以让你优雅的重启或停止你的 web 服务器。</p><p>我们可以用 <a href="https://github.com/fvbock/endless" target="_blank" rel="noopener noreferrer">fvbock/endless</a> 取代默认的 <code>ListenAndServe</code>。 请参阅 <a href="https://github.com/gin-gonic/gin/issues/296" target="_blank" rel="noopener noreferrer">问题 #296</a> 获得更多细节.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code>router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> handler<span class="token punctuation">)</span>
<span class="token comment">// [...]</span>
endless<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token string">&quot;:4242&quot;</span><span class="token punctuation">,</span> router<span class="token punctuation">)</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>endless 的替代品:</p><ul><li><a href="https://github.com/braintree/manners" target="_blank" rel="noopener noreferrer">manners</a>: A polite Go HTTP server that shuts down gracefully.</li><li><a href="https://github.com/tylerb/graceful" target="_blank" rel="noopener noreferrer">graceful</a>: Graceful is a Go package enabling graceful shutdown of an http.Handler server.</li><li><a href="https://github.com/facebookgo/grace" target="_blank" rel="noopener noreferrer">grace</a>: Graceful restart &amp; zero downtime deploy for Go servers.</li></ul><p>如果你在使用 Go 1.8，你可能并不需要这个库。考虑使用 <code>http.Server</code> 的内建 <a href="https://golang.org/pkg/net/http/#Server.Shutdown" target="_blank" rel="noopener noreferrer">Shutdown()</a> 方法优雅关闭。 查看示例 <a href="./examples/graceful-shutdown">graceful-shutdown</a>.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token comment">// +build go1.8</span>

<span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;context&quot;</span>
	<span class="token string">&quot;log&quot;</span>
	<span class="token string">&quot;net/http&quot;</span>
	<span class="token string">&quot;os&quot;</span>
	<span class="token string">&quot;os/signal&quot;</span>
	<span class="token string">&quot;syscall&quot;</span>
	<span class="token string">&quot;time&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		time<span class="token punctuation">.</span><span class="token function">Sleep</span><span class="token punctuation">(</span><span class="token number">5</span> <span class="token operator">*</span> time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;Welcome Gin Server&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	srv <span class="token operator">:=</span> <span class="token operator">&amp;</span>http<span class="token punctuation">.</span>Server<span class="token punctuation">{</span>
		Addr<span class="token punctuation">:</span>    <span class="token string">&quot;:8080&quot;</span><span class="token punctuation">,</span>
		Handler<span class="token punctuation">:</span> router<span class="token punctuation">,</span>
	<span class="token punctuation">}</span>

	<span class="token keyword">go</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token comment">// service connections</span>
		<span class="token keyword">if</span> err <span class="token operator">:=</span> srv<span class="token punctuation">.</span><span class="token function">ListenAndServe</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token operator">&amp;&amp;</span> err <span class="token operator">!=</span> http<span class="token punctuation">.</span>ErrServerClosed <span class="token punctuation">{</span>
			log<span class="token punctuation">.</span><span class="token function">Fatalf</span><span class="token punctuation">(</span><span class="token string">&quot;listen: %s\n&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	<span class="token comment">// Wait for interrupt signal to gracefully shutdown the server with</span>
	<span class="token comment">// a timeout of 5 seconds.</span>
	quit <span class="token operator">:=</span> <span class="token function">make</span><span class="token punctuation">(</span><span class="token keyword">chan</span> os<span class="token punctuation">.</span>Signal<span class="token punctuation">)</span>
	<span class="token comment">// kill (no param) default send syscall.SIGTERM</span>
	<span class="token comment">// kill -2 is syscall.SIGINT</span>
	<span class="token comment">// kill -9 is syscall.SIGKILL but can&#39;t be catch, so don&#39;t need add it</span>
	signal<span class="token punctuation">.</span><span class="token function">Notify</span><span class="token punctuation">(</span>quit<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGINT<span class="token punctuation">,</span> syscall<span class="token punctuation">.</span>SIGTERM<span class="token punctuation">)</span>
	<span class="token operator">&lt;-</span>quit
	log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Shutdown Server ...&quot;</span><span class="token punctuation">)</span>

	ctx<span class="token punctuation">,</span> cancel <span class="token operator">:=</span> context<span class="token punctuation">.</span><span class="token function">WithTimeout</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">Background</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token operator">*</span>time<span class="token punctuation">.</span>Second<span class="token punctuation">)</span>
	<span class="token keyword">defer</span> <span class="token function">cancel</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token keyword">if</span> err <span class="token operator">:=</span> srv<span class="token punctuation">.</span><span class="token function">Shutdown</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
		log<span class="token punctuation">.</span><span class="token function">Fatal</span><span class="token punctuation">(</span><span class="token string">&quot;Server Shutdown:&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	<span class="token comment">// catching ctx.Done(). timeout of 5 seconds.</span>
	<span class="token keyword">select</span> <span class="token punctuation">{</span>
	<span class="token keyword">case</span> <span class="token operator">&lt;-</span>ctx<span class="token punctuation">.</span><span class="token function">Done</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>
		log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;timeout of 5 seconds.&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	log<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">&quot;Server exiting&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="将服务器构建为一个包含模板文件的二进制文件" tabindex="-1"><a class="header-anchor" href="#将服务器构建为一个包含模板文件的二进制文件" aria-hidden="true">#</a> 将服务器构建为一个包含模板文件的二进制文件</h3><h3 id="build-a-single-binary-with-templates" tabindex="-1"><a class="header-anchor" href="#build-a-single-binary-with-templates" aria-hidden="true">#</a> Build a single binary with templates</h3><p>可以通过使用 <a href="https://github.com/jessevdk/go-assets" target="_blank" rel="noopener noreferrer">go-assets</a>，将服务器构建为包含模板的单个二进制文件</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	t<span class="token punctuation">,</span> err <span class="token operator">:=</span> <span class="token function">loadTemplate</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
		<span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>
	r<span class="token punctuation">.</span><span class="token function">SetHTMLTemplate</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;/html/index.tmpl&quot;</span><span class="token punctuation">,</span><span class="token boolean">nil</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token comment">// loadTemplate loads templates embedded by go-assets-builder</span>
<span class="token keyword">func</span> <span class="token function">loadTemplate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">(</span><span class="token operator">*</span>template<span class="token punctuation">.</span>Template<span class="token punctuation">,</span> <span class="token builtin">error</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	t <span class="token operator">:=</span> template<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">&quot;&quot;</span><span class="token punctuation">)</span>
	<span class="token keyword">for</span> name<span class="token punctuation">,</span> file <span class="token operator">:=</span> <span class="token keyword">range</span> Assets<span class="token punctuation">.</span>Files <span class="token punctuation">{</span>
		<span class="token keyword">if</span> file<span class="token punctuation">.</span><span class="token function">IsDir</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token operator">!</span>strings<span class="token punctuation">.</span><span class="token function">HasSuffix</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token string">&quot;.tmpl&quot;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span>
		<span class="token punctuation">}</span>
		h<span class="token punctuation">,</span> err <span class="token operator">:=</span> ioutil<span class="token punctuation">.</span><span class="token function">ReadAll</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
		<span class="token punctuation">}</span>
		t<span class="token punctuation">,</span> err <span class="token operator">=</span> t<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span><span class="token function">string</span><span class="token punctuation">(</span>h<span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token boolean">nil</span><span class="token punctuation">,</span> err
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> t<span class="token punctuation">,</span> <span class="token boolean">nil</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>See a complete example in the <code>https://github.com/gin-gonic/examples/tree/master/assets-in-binary</code> directory.</p><h3 id="使用自定义结构绑定表单数据" tabindex="-1"><a class="header-anchor" href="#使用自定义结构绑定表单数据" aria-hidden="true">#</a> 使用自定义结构绑定表单数据</h3><h3 id="bind-form-data-request-with-custom-struct" tabindex="-1"><a class="header-anchor" href="#bind-form-data-request-with-custom-struct" aria-hidden="true">#</a> Bind form-data request with custom struct</h3><p>以下使用自定义结构的示例:</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">type</span> StructA <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    FieldA <span class="token builtin">string</span> <span class="token string">`form:&quot;field_a&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> StructB <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    NestedStruct StructA
    FieldB <span class="token builtin">string</span> <span class="token string">`form:&quot;field_b&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> StructC <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    NestedStructPointer <span class="token operator">*</span>StructA
    FieldC <span class="token builtin">string</span> <span class="token string">`form:&quot;field_c&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> StructD <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    NestedAnonyStruct <span class="token keyword">struct</span> <span class="token punctuation">{</span>
        FieldX <span class="token builtin">string</span> <span class="token string">`form:&quot;field_x&quot;`</span>
    <span class="token punctuation">}</span>
    FieldD <span class="token builtin">string</span> <span class="token string">`form:&quot;field_d&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">GetDataB</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> b StructB
    c<span class="token punctuation">.</span><span class="token function">Bind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
        <span class="token string">&quot;a&quot;</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>NestedStruct<span class="token punctuation">,</span>
        <span class="token string">&quot;b&quot;</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>FieldB<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">GetDataC</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> b StructC
    c<span class="token punctuation">.</span><span class="token function">Bind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
        <span class="token string">&quot;a&quot;</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>NestedStructPointer<span class="token punctuation">,</span>
        <span class="token string">&quot;c&quot;</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>FieldC<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">GetDataD</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> b StructD
    c<span class="token punctuation">.</span><span class="token function">Bind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
        <span class="token string">&quot;x&quot;</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>NestedAnonyStruct<span class="token punctuation">,</span>
        <span class="token string">&quot;d&quot;</span><span class="token punctuation">:</span> b<span class="token punctuation">.</span>FieldD<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/getb&quot;</span><span class="token punctuation">,</span> GetDataB<span class="token punctuation">)</span>
    r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/getc&quot;</span><span class="token punctuation">,</span> GetDataC<span class="token punctuation">)</span>
    r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/getd&quot;</span><span class="token punctuation">,</span> GetDataD<span class="token punctuation">)</span>

    r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>Using the command <code>curl</code> command result:</p><div class="language-text ext-text line-numbers-mode"><pre class="language-text"><code>$ curl &quot;http://localhost:8080/getb?field_a=hello&amp;field_b=world&quot;
{&quot;a&quot;:{&quot;FieldA&quot;:&quot;hello&quot;},&quot;b&quot;:&quot;world&quot;}
$ curl &quot;http://localhost:8080/getc?field_a=hello&amp;field_c=world&quot;
{&quot;a&quot;:{&quot;FieldA&quot;:&quot;hello&quot;},&quot;c&quot;:&quot;world&quot;}
$ curl &quot;http://localhost:8080/getd?field_x=hello&amp;field_d=world&quot;
{&quot;d&quot;:&quot;world&quot;,&quot;x&quot;:{&quot;FieldX&quot;:&quot;hello&quot;}}
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="尝试将-body-绑定到不同的结构中" tabindex="-1"><a class="header-anchor" href="#尝试将-body-绑定到不同的结构中" aria-hidden="true">#</a> 尝试将 body 绑定到不同的结构中</h3><h3 id="try-to-bind-body-into-different-structs" tabindex="-1"><a class="header-anchor" href="#try-to-bind-body-into-different-structs" aria-hidden="true">#</a> Try to bind body into different structs</h3><p>The normal methods for binding request body consumes <code>c.Request.Body</code> and they cannot be called multiple times.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">type</span> formA <span class="token keyword">struct</span> <span class="token punctuation">{</span>
  Foo <span class="token builtin">string</span> <span class="token string">`json:&quot;foo&quot; xml:&quot;foo&quot; binding:&quot;required&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> formB <span class="token keyword">struct</span> <span class="token punctuation">{</span>
  Bar <span class="token builtin">string</span> <span class="token string">`json:&quot;bar&quot; xml:&quot;bar&quot; binding:&quot;required&quot;`</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">SomeHandler</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  objA <span class="token operator">:=</span> formA<span class="token punctuation">{</span><span class="token punctuation">}</span>
  objB <span class="token operator">:=</span> formB<span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token comment">// This c.ShouldBind consumes c.Request.Body and it cannot be reused.</span>
  <span class="token keyword">if</span> errA <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objA<span class="token punctuation">)</span><span class="token punctuation">;</span> errA <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formA`</span><span class="token punctuation">)</span>
  <span class="token comment">// Always an error is occurred by this because c.Request.Body is EOF now.</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> errB <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBind</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objB<span class="token punctuation">)</span><span class="token punctuation">;</span> errB <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formB`</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token operator">...</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>For this, you can use <code>c.ShouldBindBodyWith</code>.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">func</span> <span class="token function">SomeHandler</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  objA <span class="token operator">:=</span> formA<span class="token punctuation">{</span><span class="token punctuation">}</span>
  objB <span class="token operator">:=</span> formB<span class="token punctuation">{</span><span class="token punctuation">}</span>
  <span class="token comment">// This reads c.Request.Body and stores the result into the context.</span>
  <span class="token keyword">if</span> errA <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindBodyWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objA<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>JSON<span class="token punctuation">)</span><span class="token punctuation">;</span> errA <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formA`</span><span class="token punctuation">)</span>
  <span class="token comment">// At this time, it reuses body stored in the context.</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> errB <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindBodyWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objB<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>JSON<span class="token punctuation">)</span><span class="token punctuation">;</span> errB <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formB JSON`</span><span class="token punctuation">)</span>
  <span class="token comment">// And it can accepts other formats</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> errB2 <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">ShouldBindBodyWith</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>objB<span class="token punctuation">,</span> binding<span class="token punctuation">.</span>XML<span class="token punctuation">)</span><span class="token punctuation">;</span> errB2 <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
    c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">`the body should be formB XML`</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token operator">...</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><ul><li><code>c.ShouldBindBodyWith</code> stores body into the context before binding. This has a slight impact to performance, so you should not use this method if you are enough to call binding at once.</li><li>This feature is only needed for some formats -- <code>JSON</code>, <code>XML</code>, <code>MsgPack</code>, <code>ProtoBuf</code>. For other formats, <code>Query</code>, <code>Form</code>, <code>FormPost</code>, <code>FormMultipart</code>, can be called by <code>c.ShouldBind()</code> multiple times without any damage to performance (See <a href="https://github.com/gin-gonic/gin/pull/1341" target="_blank" rel="noopener noreferrer">#1341</a>).</li></ul><h3 id="http2-server-push" tabindex="-1"><a class="header-anchor" href="#http2-server-push" aria-hidden="true">#</a> http2 server push</h3><h3 id="http2-server-push-1" tabindex="-1"><a class="header-anchor" href="#http2-server-push-1" aria-hidden="true">#</a> http2 server push</h3><p>http.Pusher is supported only <strong>go1.8+</strong>. See the <a href="https://blog.golang.org/h2push" target="_blank" rel="noopener noreferrer">golang blog</a> for detail information.</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;html/template&quot;</span>
	<span class="token string">&quot;log&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">var</span> html <span class="token operator">=</span> template<span class="token punctuation">.</span><span class="token function">Must</span><span class="token punctuation">(</span>template<span class="token punctuation">.</span><span class="token function">New</span><span class="token punctuation">(</span><span class="token string">&quot;https&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span><span class="token string">`
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Https Test&lt;/title&gt;
  &lt;script src=&quot;/assets/app.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1 style=&quot;color:red;&quot;&gt;Welcome, Ginner!&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
`</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Static</span><span class="token punctuation">(</span><span class="token string">&quot;/assets&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;./assets&quot;</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">SetHTMLTemplate</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		<span class="token keyword">if</span> pusher <span class="token operator">:=</span> c<span class="token punctuation">.</span>Writer<span class="token punctuation">.</span><span class="token function">Pusher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> pusher <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
			<span class="token comment">// use pusher.Push() to do server push</span>
			<span class="token keyword">if</span> err <span class="token operator">:=</span> pusher<span class="token punctuation">.</span><span class="token function">Push</span><span class="token punctuation">(</span><span class="token string">&quot;/assets/app.js&quot;</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span><span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
				log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;Failed to push: %v&quot;</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span>
			<span class="token punctuation">}</span>
		<span class="token punctuation">}</span>
		c<span class="token punctuation">.</span><span class="token function">HTML</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;https&quot;</span><span class="token punctuation">,</span> gin<span class="token punctuation">.</span>H<span class="token punctuation">{</span>
			<span class="token string">&quot;status&quot;</span><span class="token punctuation">:</span> <span class="token string">&quot;success&quot;</span><span class="token punctuation">,</span>
		<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and Server in https://127.0.0.1:8080</span>
	r<span class="token punctuation">.</span><span class="token function">RunTLS</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;./testdata/server.pem&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;./testdata/server.key&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="定义路由日志记录格式" tabindex="-1"><a class="header-anchor" href="#定义路由日志记录格式" aria-hidden="true">#</a> 定义路由日志记录格式</h3><h3 id="define-format-for-the-log-of-routes" tabindex="-1"><a class="header-anchor" href="#define-format-for-the-log-of-routes" aria-hidden="true">#</a> Define format for the log of routes</h3><p>默认路由日志格式如下：</p><div class="language-text ext-text line-numbers-mode"><pre class="language-text"><code>[GIN-debug] POST   /foo                      --&gt; main.main.func1 (3 handlers)
[GIN-debug] GET    /bar                      --&gt; main.main.func2 (3 handlers)
[GIN-debug] GET    /status                   --&gt; main.main.func3 (3 handlers)
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>如果你想以给定的格式记录日志（例如 JSON 的键值或其他数据），可以使用 <code>gin.DebugPrintRputeFunc</code> 定义格式。下面的例子，我们使用标准日志包记录所有路由， 但你也可以使用符合你需求的其他日志包。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;log&quot;</span>
	<span class="token string">&quot;net/http&quot;</span>

	<span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	gin<span class="token punctuation">.</span>DebugPrintRouteFunc <span class="token operator">=</span> <span class="token keyword">func</span><span class="token punctuation">(</span>httpMethod<span class="token punctuation">,</span> absolutePath<span class="token punctuation">,</span> handlerName <span class="token builtin">string</span><span class="token punctuation">,</span> nuHandlers <span class="token builtin">int</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
		log<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;endpoint %v %v %v %v\n&quot;</span><span class="token punctuation">,</span> httpMethod<span class="token punctuation">,</span> absolutePath<span class="token punctuation">,</span> handlerName<span class="token punctuation">,</span> nuHandlers<span class="token punctuation">)</span>
	<span class="token punctuation">}</span>

	r<span class="token punctuation">.</span><span class="token function">POST</span><span class="token punctuation">(</span><span class="token string">&quot;/foo&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;foo&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/bar&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;bar&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/status&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">JSON</span><span class="token punctuation">(</span>http<span class="token punctuation">.</span>StatusOK<span class="token punctuation">,</span> <span class="token string">&quot;ok&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>

	<span class="token comment">// Listen and Server in http://0.0.0.0:8080</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="set-and-get-a-cookie" tabindex="-1"><a class="header-anchor" href="#set-and-get-a-cookie" aria-hidden="true">#</a> Set and get a cookie</h3><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">import</span> <span class="token punctuation">(</span>
    <span class="token string">&quot;fmt&quot;</span>

    <span class="token string">&quot;github.com/gin-gonic/gin&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>

    router <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/cookie&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>

        cookie<span class="token punctuation">,</span> err <span class="token operator">:=</span> c<span class="token punctuation">.</span><span class="token function">Cookie</span><span class="token punctuation">(</span><span class="token string">&quot;gin_cookie&quot;</span><span class="token punctuation">)</span>

        <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span>
            cookie <span class="token operator">=</span> <span class="token string">&quot;NotSet&quot;</span>
            c<span class="token punctuation">.</span><span class="token function">SetCookie</span><span class="token punctuation">(</span><span class="token string">&quot;gin_cookie&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;test&quot;</span><span class="token punctuation">,</span> <span class="token number">3600</span><span class="token punctuation">,</span> <span class="token string">&quot;/&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;localhost&quot;</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span>
        <span class="token punctuation">}</span>

        fmt<span class="token punctuation">.</span><span class="token function">Printf</span><span class="token punctuation">(</span><span class="token string">&quot;Cookie value: %s \n&quot;</span><span class="token punctuation">,</span> cookie<span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    router<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="testing" tabindex="-1"><a class="header-anchor" href="#testing" aria-hidden="true">#</a> Testing</h2><p><code>net/http/httptest</code>包很适合用于HTTP测试。</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">func</span> <span class="token function">setupRouter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span>gin<span class="token punctuation">.</span>Engine <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> gin<span class="token punctuation">.</span><span class="token function">Default</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token keyword">func</span><span class="token punctuation">(</span>c <span class="token operator">*</span>gin<span class="token punctuation">.</span>Context<span class="token punctuation">)</span> <span class="token punctuation">{</span>
		c<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">)</span>
	<span class="token punctuation">}</span><span class="token punctuation">)</span>
	<span class="token keyword">return</span> r
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
	r <span class="token operator">:=</span> <span class="token function">setupRouter</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	r<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span><span class="token string">&quot;:8080&quot;</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>测试代码示例如下：</p><div class="language-go ext-go line-numbers-mode"><pre class="language-go"><code><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token punctuation">(</span>
	<span class="token string">&quot;net/http&quot;</span>
	<span class="token string">&quot;net/http/httptest&quot;</span>
	<span class="token string">&quot;testing&quot;</span>

	<span class="token string">&quot;github.com/stretchr/testify/assert&quot;</span>
<span class="token punctuation">)</span>

<span class="token keyword">func</span> <span class="token function">TestPingRoute</span><span class="token punctuation">(</span>t <span class="token operator">*</span>testing<span class="token punctuation">.</span>T<span class="token punctuation">)</span> <span class="token punctuation">{</span>
	router <span class="token operator">:=</span> <span class="token function">setupRouter</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

	w <span class="token operator">:=</span> httptest<span class="token punctuation">.</span><span class="token function">NewRecorder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	req<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">:=</span> http<span class="token punctuation">.</span><span class="token function">NewRequest</span><span class="token punctuation">(</span><span class="token string">&quot;GET&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;/ping&quot;</span><span class="token punctuation">,</span> <span class="token boolean">nil</span><span class="token punctuation">)</span>
	router<span class="token punctuation">.</span><span class="token function">ServeHTTP</span><span class="token punctuation">(</span>w<span class="token punctuation">,</span> req<span class="token punctuation">)</span>

	assert<span class="token punctuation">.</span><span class="token function">Equal</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">,</span> w<span class="token punctuation">.</span>Code<span class="token punctuation">)</span>
	assert<span class="token punctuation">.</span><span class="token function">Equal</span><span class="token punctuation">(</span>t<span class="token punctuation">,</span> <span class="token string">&quot;pong&quot;</span><span class="token punctuation">,</span> w<span class="token punctuation">.</span>Body<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre><div class="line-numbers" aria-hidden="true"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="users" tabindex="-1"><a class="header-anchor" href="#users" aria-hidden="true">#</a> Users</h2><p>Awesome project lists using <a href="https://github.com/gin-gonic/gin" target="_blank" rel="noopener noreferrer">Gin</a> web framework.</p><ul><li><a href="https://github.com/drone/drone" target="_blank" rel="noopener noreferrer">drone</a>: Drone is a Continuous Delivery platform built on Docker, written in Go.</li><li><a href="https://github.com/appleboy/gorush" target="_blank" rel="noopener noreferrer">gorush</a>: A push notification server written in Go.</li><li><a href="https://github.com/fnproject/fn" target="_blank" rel="noopener noreferrer">fnproject</a>: The container native, cloud agnostic serverless platform.</li></ul><!--]--><!--[--><!--]--></div><footer class="page-meta"><!----><div class="meta-item last-updated"><span class="meta-item-label">Last Updated: </span><!----></div><!----></footer><!----><!--[--><!--]--><!----></main><!--]--></div><div class="search-page" role="search"><span class="search-close"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512" width="28" height="28" fill="currentColor"><path d="M224 416c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L224 338.8l169.4-169.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-192 192C240.4 412.9 232.2 416 224 416z"></path></svg></span><div class="gungnir-search-box"><input placeholder="$ grep ..." autocomplete="off" spellcheck="false" value><!----></div></div><div class="menu-btn-container"><div class="menu-btn-wrapper"><div class="menu-btn"><div style="" class="menu-btn-icon"><span></span><span></span><span></span></div><div style="display:none;" class="menu-text">0</div><svg class="menu-progress"><circle class="menu-border" cx="50%" cy="50%" r="48%" style="stroke-dasharray:0% 314.15926%;"></circle></svg></div><div class="menu-btn-child-wrapper"><div class="toggle-dark-button menu-btn-child" title="toggle dark mode"><svg class="ov-icon" style="font-size:1.2em;display:none;" aria-hidden="true" width="19.2" height="19.2" viewbox="-43.52 -43.52 599.04 599.04" fill="currentColor"><path d="M256 160c-52.9 0-96 43.1-96 96s43.1 96 96 96 96-43.1 96-96-43.1-96-96-96zm246.4 80.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.4-94.8c-6.4-12.8-24.6-12.8-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4c-12.8 6.4-12.8 24.6 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.4-33.5 47.3 94.7c6.4 12.8 24.6 12.8 31 0l47.3-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3c13-6.5 13-24.7.2-31.1zm-155.9 106c-49.9 49.9-131.1 49.9-181 0-49.9-49.9-49.9-131.1 0-181 49.9-49.9 131.1-49.9 181 0 49.9 49.9 49.9 131.1 0 181z"/></svg><svg class="ov-icon" style="font-size:1.2em;display:none;" aria-hidden="true" width="19.2" height="19.2" viewbox="-43.52 -43.52 599.04 599.04" fill="currentColor"><path d="M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 00283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z"/></svg><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-43.52 -43.52 599.04 599.04" fill="currentColor"><path d="M224 96l16-32 32-16-32-16-16-32-16 32-32 16 32 16 16 32zM80 160l26.66-53.33L160 80l-53.34-26.67L80 0 53.34 53.33 0 80l53.34 26.67L80 160zm352 128l-26.66 53.33L352 368l53.34 26.67L432 448l26.66-53.33L512 368l-53.34-26.67L432 288zm70.62-193.77L417.77 9.38C411.53 3.12 403.34 0 395.15 0c-8.19 0-16.38 3.12-22.63 9.38L9.38 372.52c-12.5 12.5-12.5 32.76 0 45.25l84.85 84.85c6.25 6.25 14.44 9.37 22.62 9.37 8.19 0 16.38-3.12 22.63-9.37l363.14-363.15c12.5-12.48 12.5-32.75 0-45.24zM359.45 203.46l-50.91-50.91 86.6-86.6 50.91 50.91-86.6 86.6z"/></svg></div><div class="menu-btn-child"><svg class="ov-icon" style="font-size:1.7999999999999998em;" aria-hidden="true" width="28.799999999999997" height="28.799999999999997" viewbox="-75.52 -43.52 599.04 599.04" fill="currentColor"><path d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"/></svg></div><div class="menu-btn-child"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-75.52 -43.52 599.04 599.04" fill="currentColor"><path d="M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z"/></svg></div><!----><div class="toggle-sidebar-button menu-btn-child menu-btn-sidebar" title="toggle sidebar" aria-expanded="false" role="button" tabindex="0"><svg class="ov-icon" style="font-size:1.2em;" aria-hidden="true" width="19.2" height="19.2" viewbox="-1.6 -1.6 19.2 19.2" fill="currentColor"><path d="M14 2a1 1 0 011 1v10a1 1 0 01-1 1H2a1 1 0 01-1-1V3a1 1 0 011-1h12zM2 1a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V3a2 2 0 00-2-2H2z"/><path d="M3 4a1 1 0 011-1h2a1 1 0 011 1v8a1 1 0 01-1 1H4a1 1 0 01-1-1V4z"/></svg></div></div></div></div><!----></div><!--]--></div>
    <script type="module" src="/assets/app.80e5dc69.js" defer></script>
  </body>
</html>
